From 31dbe09725cc3cddbb422a7dc196fed262803a63 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Fri, 23 Oct 2026 10:17:41 -0400 Subject: [PATCH 01/46] Track B insured status: quarters of coverage and fully, currently and disability insured status Max ruled d1802: the rules lane builds insured status for B6a's monthly claiming hazard, and the open-population lane's OP8(d) will call it for entrants. Nothing in the repository decided insured status before. The new reference implements Act 213, 214, 216(i) and 223(c) as a sealed, person-month API: - Quarters of coverage: quarterly wages before 1978, the self-employment and agricultural rules, gift QCs for maximum earnings, annual increments 1978-2027, favourable assignment, and exclusions. - Fully insured (6 to 40 elapsed years, counted from birth, with the pre-1913 male cohorts), currently insured (6 of 13 quarters), and disability insured (20/40, special status before 31, subsequent periods, blindness), with the date last insured. - Every earnings year declares its provenance: observed, convention-filled (with an id) or unknown. Unknown years are bounded at their lowest and highest QC counts. A status is returned only if both bounds agree; otherwise it is refused by name and stays in the shared denominator. - Direct QC input (a 0-4 count after 1977, quarter flags before), evaluation at a stated month, an optional totalization input (refused until built), and a coverage-end month for emigrants. Specialist paths (deemed status, the SSPA alien-worker rule, railroad and military credits, Medicare government employment, fiscal and short taxable years, simplified pre-1951 methods) are named refusals. The tests reproduce the RS 00301 and CFR worked examples, compare the 213(d) formula on the pinned NAWI with the published chart, compare POMS with OACT, and compare the CFR 404.115 cohort chart. Hypothesis properties cover monotonicity in QCs and the date last insured, the soundness of the unknown-year bounds, and the shared input and seal contract. Co-Authored-By: Claude Opus 5.5 --- scripts/first_estimates_birth_evidence.py | 3 + .../track_b/_insured_status_qc.py | 300 ++ src/populace_dynamics/track_b/_provenance.py | 7 +- .../track_b/insured_status.py | 983 +++++ .../data/track_b/insured_status_examples.yaml | 864 ++++ .../insured_status_mutation_checks.json | 418 ++ .../track_b/insured_status_sources/README.md | 113 + .../ecfr_20cfr404_subpart_b.xml | 710 ++++ .../lii_usc_42_413_excerpts.txt | 7 + .../lii_usc_42_414_excerpts.txt | 5 + .../lii_usc_42_416_excerpts.txt | 7 + .../lii_usc_42_423_excerpts.txt | 1 + .../insured_status_sources/manifest.json | 601 +++ .../poms_rs_00301_000_toc.html | 499 +++ .../poms_rs_00301_101.html | 762 ++++ .../poms_rs_00301_102.html | 3545 +++++++++++++++++ .../poms_rs_00301_105.html | 504 +++ .../poms_rs_00301_106.html | 470 +++ .../poms_rs_00301_107.html | 415 ++ .../poms_rs_00301_110.html | 335 ++ .../poms_rs_00301_120.html | 467 +++ .../poms_rs_00301_122.html | 300 ++ .../poms_rs_00301_130.html | 364 ++ .../poms_rs_00301_131.html | 284 ++ .../poms_rs_00301_132.html | 402 ++ .../poms_rs_00301_140.html | 592 +++ .../poms_rs_00301_147.html | 1018 +++++ .../poms_rs_00301_148.html | 501 +++ .../poms_rs_00301_149.html | 263 ++ .../poms_rs_00301_150.html | 405 ++ .../poms_rs_00301_160.html | 440 ++ .../poms_rs_00301_161.html | 296 ++ .../poms_rs_00301_200.html | 297 ++ .../poms_rs_00301_210.html | 290 ++ .../poms_rs_00301_220.html | 283 ++ .../poms_rs_00301_230.html | 332 ++ .../poms_rs_00301_240.html | 309 ++ .../poms_rs_00301_250.html | 1159 ++++++ .../poms_rs_00301_301.html | 285 ++ .../poms_rs_00301_310.html | 345 ++ .../poms_rs_00301_315.html | 447 +++ .../poms_rs_00301_320.html | 346 ++ .../poms_rs_00301_325.html | 313 ++ .../poms_rs_00301_340.html | 359 ++ .../poms_rs_00301_345.html | 643 +++ .../poms_rs_00301_350.html | 487 +++ .../poms_rs_00301_470.html | 285 ++ .../poms_rs_00301_475.html | 366 ++ .../poms_rs_00301_480.html | 347 ++ .../poms_rs_00301_600.html | 324 ++ .../poms_rs_00301_800.html | 268 ++ .../insured_status_sources/ssa_oact_qc.txt | 160 + .../estimates/test_birth_evidence_artifact.py | 4 + ...ack_b_gross_benefits_fix_round_13_audit.py | 43 + ...b_gross_benefits_fix_round_15_arguments.py | 36 +- ...b_gross_benefits_fix_round_15_receivers.py | 26 +- tests/test_track_b_input_schema.py | 43 +- tests/test_track_b_insured_status.py | 929 +++++ tests/test_track_b_insured_status_contract.py | 304 ++ tests/test_track_b_insured_status_qc.py | 411 ++ tests/test_track_b_insured_status_sources.py | 531 +++ 61 files changed, 25843 insertions(+), 10 deletions(-) create mode 100644 src/populace_dynamics/track_b/_insured_status_qc.py create mode 100644 src/populace_dynamics/track_b/insured_status.py create mode 100644 tests/data/track_b/insured_status_examples.yaml create mode 100644 tests/data/track_b/insured_status_mutation_checks.json create mode 100644 tests/data/track_b/insured_status_sources/README.md create mode 100644 tests/data/track_b/insured_status_sources/ecfr_20cfr404_subpart_b.xml create mode 100644 tests/data/track_b/insured_status_sources/lii_usc_42_413_excerpts.txt create mode 100644 tests/data/track_b/insured_status_sources/lii_usc_42_414_excerpts.txt create mode 100644 tests/data/track_b/insured_status_sources/lii_usc_42_416_excerpts.txt create mode 100644 tests/data/track_b/insured_status_sources/lii_usc_42_423_excerpts.txt create mode 100644 tests/data/track_b/insured_status_sources/manifest.json create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_000_toc.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_101.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_102.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_105.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_106.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_107.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_110.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_120.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_122.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_130.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_131.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_132.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_140.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_147.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_148.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_149.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_150.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_160.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_161.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_200.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_210.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_220.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_230.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_240.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_250.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_301.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_310.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_315.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_320.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_325.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_340.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_345.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_350.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_470.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_475.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_480.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_600.html create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_800.html create mode 100644 tests/data/track_b/insured_status_sources/ssa_oact_qc.txt create mode 100644 tests/test_track_b_insured_status.py create mode 100644 tests/test_track_b_insured_status_contract.py create mode 100644 tests/test_track_b_insured_status_qc.py create mode 100644 tests/test_track_b_insured_status_sources.py diff --git a/scripts/first_estimates_birth_evidence.py b/scripts/first_estimates_birth_evidence.py index ff6407ab0..c4b2e6b07 100644 --- a/scripts/first_estimates_birth_evidence.py +++ b/scripts/first_estimates_birth_evidence.py @@ -314,6 +314,9 @@ # nothing in the historical projection imports it. Path("src/populace_dynamics/track_b/gross_benefits.py"), Path("src/populace_dynamics/track_b/_provenance.py"), + # Insured status and QC accounting are opt-in statutory references. + Path("src/populace_dynamics/track_b/insured_status.py"), + Path("src/populace_dynamics/track_b/_insured_status_qc.py"), # R2 statutory payment mechanics also stay outside birth evidence. Path("src/populace_dynamics/track_b/ret_grace.py"), Path("src/populace_dynamics/track_b/ret_ledger.py"), diff --git a/src/populace_dynamics/track_b/_insured_status_qc.py b/src/populace_dynamics/track_b/_insured_status_qc.py new file mode 100644 index 000000000..0496d0cbb --- /dev/null +++ b/src/populace_dynamics/track_b/_insured_status_qc.py @@ -0,0 +1,300 @@ +"""Private quarter-of-coverage arithmetic for the statutory reference. + +Verification class: statutory conformance on invented and published cases. +These helpers admit no population, behavioral, or forecast claim. The +public insured-status boundary validates and owns its inputs once; helpers +consume those normalized primitives and do not establish public provenance. + +Authority: Act 213, 20 CFR 404.140-.146, and POMS RS 00301.200-.350. +Integer quarter identifiers are ``4 * year + quarter - 1``. Flexible +credits are assigned separately for each statutory window, as RS 00301.230 +requires, rather than silently fixing all annual credits to year-end. +""" + +from datetime import date +from fractions import Fraction +from itertools import combinations +from types import MappingProxyType + +__all__ = [] + +# POMS RS 00301.250 (1978-2026) and captured OACT QC history (2027). +QC_AMOUNTS = MappingProxyType( + dict( + zip( + range(1978, 2028), + ( + 250, + 260, + 290, + 310, + 340, + 370, + 390, + 410, + 440, + 460, + 470, + 500, + 520, + 540, + 570, + 590, + 620, + 630, + 640, + 670, + 700, + 740, + 780, + 830, + 870, + 890, + 900, + 920, + 970, + 1000, + 1050, + 1090, + 1120, + 1120, + 1130, + 1160, + 1200, + 1220, + 1260, + 1300, + 1320, + 1360, + 1410, + 1470, + 1510, + 1640, + 1730, + 1810, + 1890, + 1970, + ), + strict=True, + ) + ) +) + + +class _UnsupportedQC(Exception): + """Private indication translated to the public layer's own refusal.""" + + def __init__(self, reason: str): + self.reason = reason + super().__init__(reason) + + +def _quarter_id(year: int, quarter: int) -> int: + return year * 4 + quarter - 1 + + +def _year_quarters(year: int) -> tuple[int, ...]: + return tuple(range(year * 4, year * 4 + 4)) + + +def _date_quarter(value: date) -> int: + return _quarter_id(value.year, (value.month - 1) // 3 + 1) + + +def _qc_amount_from_nawi(nawi: Fraction, prior_amount: int) -> int: + """Act 213(d)(2): exact index, nearest $10 with $5 ties upward.""" + indexed = Fraction(250) * nawi / Fraction("9226.48") + rounded = ((indexed + 5) // 10) * 10 + return max(prior_amount, rounded) + + +def _post1977_qc_count( + year: int, wages: Fraction, self_employment: Fraction +) -> int: + """Act 213(a)(2)(A)(ii); earnings are already calendar-year credited.""" + return min(4, (wages + self_employment) // QC_AMOUNTS[year]) + + +def _annual_wage_limit(year: int) -> int: + """POMS RS 00301.345B.1's pre-1978 maximum taxable wage chart.""" + for last, amount in ( + (1950, 3000), + (1954, 3600), + (1958, 4200), + (1965, 4800), + (1967, 6600), + (1971, 7800), + (1972, 9000), + (1973, 10800), + (1974, 13200), + (1975, 14100), + (1976, 15300), + (1977, 16500), + ): + if year <= last: + return amount + raise _UnsupportedQC("pre1978_wage_limit_year_unsupported") + + +def _pre1978_qc_credits( + year: int, + quarterly_wages: tuple[Fraction, ...], + self_employment: Fraction, + agricultural_wages: Fraction, +) -> tuple[tuple[int, ...], int]: + """Fixed wage/SE quarters and additional flexible agricultural QCs. + + Quarterly wages are covered nonagricultural wages (also covered + agricultural wages in 1951-54). Calendar-year SEI >= $400 covers four + quarters. Separate annual agricultural wages are supported for 1955-77; + their floor-$100 QCs occupy quarters not otherwise credited. Maximum + taxable wages, or combined wages and SEI, give four gift QCs. Exclusions + are applied afterwards and cannot turn an excluded fixed QC flexible. + """ + if year == 1937 and ( + any(quarterly_wages) or self_employment or agricultural_wages + ): + # Act 213(b) half-year allocation has an age-65 exception. The + # annual interface can consume explicitly credited quarter flags, + # but cannot infer this historical allocation from wages alone. + raise _UnsupportedQC("1937_earnings_allocation_unsupported") + if year < 1955 and agricultural_wages: + raise _UnsupportedQC("pre1955_agricultural_allocation_unsupported") + if year < 1951 and self_employment: + raise _UnsupportedQC("pre1951_self_employment_unsupported") + quarters = _year_quarters(year) + wages = sum(quarterly_wages) + agricultural_wages + if ( + wages + self_employment >= _annual_wage_limit(year) + or self_employment >= 400 + ): + return quarters, 0 + fixed = tuple( + quarter + for quarter, wages in zip(quarters, quarterly_wages, strict=True) + if wages >= 50 + ) + flexible = min(4 - len(fixed), agricultural_wages // 100) + return fixed, flexible + + +def _allowed_quarters( + year: int, + *, + through_quarter: int, + death_quarter: int | None = None, + coverage_end_quarter: int | None = None, + disability_periods: tuple[tuple[int, int], ...] = (), +) -> tuple[int, ...]: + """404.146: begun, not after death/exit, outside disability interiors. + + Disability endpoints themselves remain eligible. A caller that elects + not to take a period into consideration under 404.146(d)(2) omits it. + Coverage-end is the explicit entrant/emigrant contract, not an additional + statutory disability exclusion. + """ + last = min( + value + for value in (through_quarter, death_quarter, coverage_end_quarter) + if value is not None + ) + return tuple( + quarter + for quarter in _year_quarters(year) + if quarter <= last + and not any(start < quarter < end for start, end in disability_periods) + ) + + +def _assignment_candidates( + fixed: tuple[int, ...], + flexible_count: int, + allowed: tuple[int, ...], +) -> tuple[tuple[int, ...], ...]: + """All feasible assignments, after exclusions and without duplicates.""" + permitted = frozenset(allowed) + retained = frozenset(fixed) & permitted + vacant = tuple(sorted(permitted - retained)) + count = min(flexible_count, len(vacant)) + return tuple( + tuple(sorted((*retained, *choice))) + for choice in combinations(vacant, count) + ) + + +def _assign_qcs( + fixed: tuple[int, ...], + flexible_count: int, + allowed: tuple[int, ...], + window: tuple[int, ...] = (), +) -> tuple[int, ...]: + """Maximize this window; otherwise keep ordinary agricultural order. + + Act 213(a)(2)(B)(iv) assigns pre-1978 agricultural credits to the last + uncredited quarters, with reassignment to meet the stated tests. The + post-1977 rule has no ordinary latest-quarter preference, so its ties + use the earliest assignment deterministically. + """ + target = frozenset(window) + latest = bool(allowed) and allowed[0] // 4 < 1978 + return min( + _assignment_candidates(fixed, flexible_count, allowed), + key=lambda candidate: ( + -len(target.intersection(candidate)), + tuple(-q for q in reversed(candidate)) if latest else candidate, + ), + ) + + +def _allocate_sei_pre1978( + start: date, end: date, self_employment: Fraction +) -> tuple[tuple[int, Fraction], ...]: + """404.142 / RS 00301.340: equal shares in last at most four quarters. + + This is allocation arithmetic for already declared covered SEI, not a + determination of taxable income. The public annual interface requires + calendar-year declarations and does not infer a fiscal taxable year. + """ + last = _date_quarter(end) + first = max(_date_quarter(start), last - 3) + amount = self_employment / (last - first + 1) + return tuple((quarter, amount) for quarter in range(first, last + 1)) + + +def _allocate_sei_post1977( + start: date, end: date, self_employment: Fraction +) -> tuple[tuple[int, Fraction], ...]: + """404.144: full months, including the month in which the year ends.""" + if start.year == end.year: + return ((start.year, self_employment),) + months_first = 12 - start.month + (start.day == 1) + months_last = end.month + total = months_first + months_last + return ( + (start.year, self_employment * months_first / total), + (end.year, self_employment * months_last / total), + ) + + +def _pre1978_taxable_qcs( + start: date, + end: date, + self_employment: Fraction, + wages: Fraction = Fraction(0), +) -> tuple[int, ...]: + """404.141(d)(2), .142: fiscal-year SE/gift-credit worked arithmetic. + + At the maximum, every partly included quarter is credited, including a + fifth calendar quarter; otherwise SEI is allocated to at most four. + Wage QCs themselves are supplied separately by their actual quarters. + """ + limit_year = start.year if start.year >= 1972 else end.year + if self_employment + wages >= _annual_wage_limit(limit_year): + return tuple(range(_date_quarter(start), _date_quarter(end) + 1)) + return tuple( + quarter + for quarter, amount in _allocate_sei_pre1978( + start, end, self_employment + ) + if amount >= 100 + ) diff --git a/src/populace_dynamics/track_b/_provenance.py b/src/populace_dynamics/track_b/_provenance.py index d5c3cae16..928661fda 100644 --- a/src/populace_dynamics/track_b/_provenance.py +++ b/src/populace_dynamics/track_b/_provenance.py @@ -14,7 +14,8 @@ caller-declared attribution of an earlier genuine result or refusal. The contract excludes code accessing private names, monkeypatching modules, or mutating an input from another thread during a call. -One private capability seals every declared G, R2 and R3 result, refusal, +One private capability seals every declared G, R2, R3 and insured-status +result, refusal, outcome and denominator. Public construction and copying are input errors; serialization is rejected. Persist declared inputs and recompute instead. """ @@ -977,7 +978,9 @@ def _external_declarations(): def _schema(annotation, module, *, name="", owner=None): origin, args = get_origin(annotation), get_args(annotation) - exact = module.endswith((".arf", ".recompute", ".ret_ledger")) + exact = module.endswith( + (".arf", ".recompute", ".ret_ledger", ".insured_status") + ) if annotation is object or annotation is Fraction: return lambda value, label: _numeric_schema( value, diff --git a/src/populace_dynamics/track_b/insured_status.py b/src/populace_dynamics/track_b/insured_status.py new file mode 100644 index 000000000..51614ed71 --- /dev/null +++ b/src/populace_dynamics/track_b/insured_status.py @@ -0,0 +1,983 @@ +"""Track B insured status, version track-b-insured-v1. + +Verification class: statutory conformance. Admitted scope: declared invented +histories and captured statutory examples only; no population, behavioral, +or forecast claim. Act 213, 214, 216(i), 223(c); 20 CFR 404 subpart B; +POMS RS 00301. Every year is declared, including zero and unknown years. +The query month is a hypothetical entitlement/onset month, not a finding of +medical disability or administrative entitlement. Annual QC assignment is +favorable and retrospective; callers must supply only information available +at their decision time. Each test returns its own assignment witness. + +All public declarations use the shared exact-type schema. Ordered sequences +retain multiplicity; conditions are membership collections. Computed values, +refusals and evaluator rows use the common Track B provenance seal. Public +calls validate once before coverage decisions. Persist inputs and recompute. +""" + +from __future__ import annotations + +import calendar +from collections.abc import Callable, Mapping +from dataclasses import dataclass +from datetime import date, timedelta +from enum import Enum +from fractions import Fraction +from itertools import product +from math import prod +from types import MappingProxyType + +from populace_dynamics.track_b._insured_status_qc import ( + _allowed_quarters, + _assign_qcs, + _assignment_candidates, + _post1977_qc_count, + _pre1978_qc_credits, + _qc_amount_from_nawi, + _UnsupportedQC, +) +from populace_dynamics.track_b._provenance import ( + _check_refusal, + _check_seal, + _checked_result, + _computed, + _declared_input, + _sealed_refusal, + _sealed_result, + _SealedOutcome, + _SealedResult, + _validated_entry, +) +from populace_dynamics.track_b.gross_benefits import ( + FamilyConfigurationUnsupported, + InvalidFamilyInput, + _check_evaluation_inputs, +) + +VERSION = "track-b-insured-v1" + + +class EarningsProvenance(Enum): + OBSERVED = "observed" + CONVENTION_FILLED = "convention_filled" + UNKNOWN = "unknown" + + +class Sex(Enum): + MALE = "male" + FEMALE = "female" + + +class InsuredTest(Enum): + ALL = "all" + FULLY = "fully" + CURRENTLY = "currently" + DISABILITY = "disability" + + +class CoverageCondition(Enum): + DEEMED_FULLY_INSURED = "deemed_fully_insured" + TRANSITIONAL_INSURED = "transitional_insured" + RAILROAD_CREDITS = "railroad_credits" + MILITARY_CREDITS = "military_credits" + MEDICARE_GOVERNMENT_EMPLOYMENT = "medicare_government_employment" + EARNED_BASIS = "earned_basis" + DISABILITY_BEFORE_1956 = "disability_before_1956" + FISCAL_TAXABLE_YEAR = "fiscal_taxable_year" + SHORT_TAXABLE_YEAR = "short_taxable_year" + SIMPLIFIED_PRE1951 = "simplified_pre1951" + + +class InsuredUnsupportedReason(Enum): + UNKNOWN_EARNINGS = "unknown_earnings_years_decide_status" + TOTALIZATION = "totalization_credits_unsupported" + DEEMED_FULLY_INSURED = "deemed_fully_insured_unsupported" + TRANSITIONAL_INSURED = "transitional_insured_unsupported" + ALIEN_WORKER = "alien_worker_sspa211_unsupported" + RAILROAD_CREDITS = "railroad_credits_unsupported" + MILITARY_CREDITS = "military_credits_unsupported" + MEDICARE_GOVERNMENT_EMPLOYMENT = ( + "medicare_government_employment_unsupported" + ) + EARNED_BASIS = "earned_basis_unsupported" + DISABILITY_BEFORE_1956 = "disability_before_1956_unsupported" + FISCAL_TAXABLE_YEAR = "fiscal_taxable_year_unsupported" + SHORT_TAXABLE_YEAR = "short_taxable_year_unsupported" + SIMPLIFIED_PRE1951 = "simplified_pre1951_unsupported" + PRE1955_AGRICULTURE = "pre1955_agricultural_allocation_unsupported" + PRE1951_SELF_EMPLOYMENT = "pre1951_self_employment_unsupported" + EARNINGS_1937 = "1937_earnings_allocation_unsupported" + QC_YEAR = "qc_amount_year_unsupported" + HISTORICAL_ENTITLEMENT = "entitlement_before_1968_unsupported" + HISTORICAL_BLINDNESS = "blindness_before_1973_unsupported" + HISTORICAL_SUBSEQUENT = "subsequent_special_before_1983_unsupported" + ASSIGNMENT_COMPLEXITY = "disability_boundary_assignments_unsupported" + + +@_sealed_refusal(InsuredUnsupportedReason) +class InsuredConfigurationUnsupported(FamilyConfigurationUnsupported): + """A retained insured-status refusal bound to this module's reason enum.""" + + +def _refuse(reason, detail): + raise _computed(InsuredConfigurationUnsupported, reason, detail) + + +def _month(value, label): + if value.day != 1: + raise InvalidFamilyInput(f"{label} must be the first day of a month") + + +def _qid(value): + return value.year * 4 + (value.month - 1) // 3 + + +def _qdate(qid): + year, quarter = divmod(qid, 4) + return date(year, quarter * 3 + 1, 1) + + +def _qend(qid): + year, quarter = divmod(qid, 4) + month = quarter * 3 + 3 + return date(year, month, calendar.monthrange(year, month)[1]) + + +def _attain(birth, age): + year = birth.year + age + day = min(birth.day, calendar.monthrange(year, birth.month)[1]) + return date(year, birth.month, day) - timedelta(days=1) + + +@_declared_input +@dataclass(frozen=True) +class CoverageYear: + provenance: EarningsProvenance + convention_id: str | None = None + wages: Fraction | None = None + self_employment: Fraction | None = None + quarterly_wages: tuple[Fraction, ...] | None = None + agricultural_wages: Fraction | None = None + qc_count: int | None = None + qc_quarters: tuple[bool, ...] | None = None + + def __post_init__(self): + convention = self.provenance is EarningsProvenance.CONVENTION_FILLED + if convention != (self.convention_id is not None): + raise InvalidFamilyInput("Only convention-filled years need an id") + if convention and not self.convention_id.strip(): + raise InvalidFamilyInput("Convention identifier must be nonempty") + amounts = (self.wages, self.self_employment, self.agricultural_wages) + for amount in amounts: + if amount is not None and amount < 0: + raise InvalidFamilyInput("Covered earnings cannot be negative") + if self.quarterly_wages is not None: + if len(self.quarterly_wages) != 4 or any( + value < 0 for value in self.quarterly_wages + ): + raise InvalidFamilyInput( + "Four nonnegative wage quarters needed" + ) + if self.qc_count is not None and not 0 <= self.qc_count <= 4: + raise InvalidFamilyInput( + "Annual QC count must be between zero and four" + ) + if self.qc_quarters is not None and len(self.qc_quarters) != 4: + raise InvalidFamilyInput("Four quarterly QC flags needed") + earnings = any(value is not None for value in amounts) or ( + self.quarterly_wages is not None + ) + direct = self.qc_count is not None or self.qc_quarters is not None + if self.provenance is EarningsProvenance.UNKNOWN: + if earnings or direct: + raise InvalidFamilyInput("Unknown years cannot contain values") + elif earnings == direct: + raise InvalidFamilyInput( + "Declare either earnings or QCs, never both" + ) + if self.qc_count is not None and self.qc_quarters is not None: + raise InvalidFamilyInput( + "Declare count or quarterly flags, not both" + ) + + +@_declared_input +@dataclass(frozen=True) +class DisabilityPeriod: + start: date + end: date + special_insured: bool = False + + def __post_init__(self): + if self.end < self.start: + raise InvalidFamilyInput("Disability period ends before it starts") + + +@_declared_input +@dataclass(frozen=True) +class Person: + birth_date: date + sex: Sex | None = None + death_date: date | None = None + disability_onset: date | None = None + prior_disability_periods: tuple[DisabilityPeriod, ...] = () + statutory_blindness: bool = False + conditions: frozenset[CoverageCondition] = frozenset() + alien_worker: bool = False + ssn_assignment_date: date | None = None + ssn_never_assigned: bool = False + rib_entitlement_month: date | None = None + dib_entitlement_month: date | None = None + + def __post_init__(self): + if not 1870 <= self.birth_date.year <= 9900: + raise InvalidFamilyInput("Birth year outside supported calendar") + if self.birth_date < date(1913, 1, 2) and self.sex is None: + raise InvalidFamilyInput("Pre-1913 cohorts require declared sex") + for value in (self.death_date, self.disability_onset): + if value is not None and value < self.birth_date: + raise InvalidFamilyInput("Event precedes birth") + if ( + self.death_date is not None + and self.disability_onset is not None + and self.disability_onset > self.death_date + ): + raise InvalidFamilyInput("Disability onset follows death") + periods = sorted(self.prior_disability_periods, key=lambda p: p.start) + for i, period in enumerate(periods): + if period.start < self.birth_date or ( + self.death_date is not None and period.end > self.death_date + ): + raise InvalidFamilyInput("Disability period outside lifetime") + if i and _qid(period.start) <= _qid(periods[i - 1].end): + raise InvalidFamilyInput("Disability periods overlap quarters") + if period.special_insured and _qid(period.start) >= _qid( + _attain(self.birth_date, 31) + ): + raise InvalidFamilyInput( + "Prior special onset must precede age31" + ) + if ( + self.alien_worker + and self.ssn_assignment_date is None + and not self.ssn_never_assigned + ): + raise InvalidFamilyInput( + "Alien worker requires assignment date or explicit never-assigned fact" + ) + if self.ssn_never_assigned and self.ssn_assignment_date is not None: + raise InvalidFamilyInput( + "Unassigned SSN cannot have assignment date" + ) + if ( + self.ssn_assignment_date is not None + and self.ssn_assignment_date < self.birth_date + ): + raise InvalidFamilyInput("SSN assignment precedes birth") + for event in (self.rib_entitlement_month, self.dib_entitlement_month): + if event is not None: + _month(event, "entitlement month") + if event < self.birth_date.replace(day=1) or ( + self.death_date is not None + and event > self.death_date.replace(day=1) + ): + raise InvalidFamilyInput("Entitlement outside lifetime") + object.__setattr__(self, "prior_disability_periods", tuple(periods)) + + +@_sealed_result +@dataclass(frozen=True) +class StatusDecision(_SealedResult): + insured: bool + qc_count_lower: int + qc_count_upper: int + required: int + window: tuple[int, ...] + assigned_quarters: tuple[int, ...] + rule: str + upper_required: int + upper_window: tuple[int, ...] + upper_assigned_quarters: tuple[int, ...] + upper_rule: str + fully_required: int + upper_fully_required: int + fully_qc_count_lower: int + fully_qc_count_upper: int + + +@_sealed_result +@dataclass(frozen=True) +class DLIRange(_SealedResult): + lower: date | None + upper: date | None + right_censored: bool + + +@_sealed_result +@dataclass(frozen=True) +class InsuredStatus(_SealedResult): + version: str + month: date + fully: StatusDecision | None + currently: StatusDecision | None + disability: StatusDecision | None + dli: DLIRange | None + qcs_by_year: Mapping[int, tuple[int, int]] + assigned_quarters: Mapping[int, tuple[int, ...]] + unknown_years: tuple[int, ...] + convention_years: Mapping[int, str] + decided_despite_unknowns: bool + + +def _requirement(person, at, periods=(), *, onset=True, for_disability=False): + start = max(1951, _attain(person.birth_date, 21).year + 1) + end = min(at.year, _attain(person.birth_date, 62).year) + if person.sex is Sex.MALE and person.birth_date < date(1913, 1, 2): + end = min( + at.year, + ( + _attain(person.birth_date, 65).year + if person.birth_date < date(1911, 1, 2) and not for_disability + else 1975 + ), + ) + if person.death_date is not None: + end = min(end, person.death_date.year) + if ( + onset + and person.disability_onset is not None + and not person.statutory_blindness + ): + end = min(end, person.disability_onset.year) + elapsed = sum( + not any(a.year <= year <= b.year for a, b in periods) + for year in range(start, end) + ) + return min(40, max(6, elapsed)) + + +@_validated_entry +def fully_insured_requirement(person: Person, month: date) -> int: + """One QC per elapsed year, bounded by six and forty (214(a)).""" + _month(month, "month") + if month < person.birth_date.replace(day=1): + raise InvalidFamilyInput("Query precedes birth") + if ( + person.disability_onset is not None + and person.disability_onset.replace(day=1) > month + ): + raise InvalidFamilyInput("Disability onset follows query month") + if any(p.end >= month for p in person.prior_disability_periods): + raise InvalidFamilyInput("Prior disability period follows query month") + periods = tuple((p.start, p.end) for p in person.prior_disability_periods) + return _requirement(person, month, periods) + + +@_validated_entry +def qc_amount_from_nawi(nawi: Fraction, prior_amount: int) -> int: + """213(d): exact indexed amount, nearest $10 with $5 ties upward.""" + if nawi <= 0 or prior_amount < 250 or prior_amount % 10: + raise InvalidFamilyInput( + "Positive NAWI and prior statutory increment needed" + ) + return _qc_amount_from_nawi(nawi, prior_amount) + + +def _validate_history(person, years, month, coverage_end_month, credits): + _month(month, "month") + if month.year > 9990 or month < person.birth_date.replace(day=1): + raise InvalidFamilyInput("Query outside person's calendar") + if ( + person.disability_onset is not None + and person.disability_onset.replace(day=1) > month + ): + raise InvalidFamilyInput("Disability onset follows query month") + if any( + event is not None and event > month + for event in ( + person.rib_entitlement_month, + person.dib_entitlement_month, + ) + ): + raise InvalidFamilyInput("Entitlement follows query month") + if coverage_end_month is not None: + _month(coverage_end_month, "coverage_end_month") + if coverage_end_month < person.birth_date.replace(day=1): + raise InvalidFamilyInput("Coverage end precedes birth") + if any(not credit.strip() for credit in credits): + raise InvalidFamilyInput( + "Totalization credit identifiers must be nonempty" + ) + end = min( + month.year, + ( + coverage_end_month.year + if coverage_end_month is not None + else month.year + ), + ( + person.death_date.year + if person.death_date is not None + else month.year + ), + ) + expected = set(range(max(1937, person.birth_date.year), end + 1)) + if set(years) != expected: + raise InvalidFamilyInput( + "Every coverage year must be declared; missing=" + f"{sorted(expected - set(years))}, extra={sorted(set(years) - expected)}" + ) + for period in person.prior_disability_periods: + if period.end >= month or ( + person.disability_onset is not None + and period.end >= person.disability_onset + ): + raise InvalidFamilyInput( + "Prior disability period must precede current event" + ) + for year, row in years.items(): + if year < 1978: + if row.qc_count is not None or row.wages is not None: + raise InvalidFamilyInput( + "Pre1978 needs quarterly wages or QC flags" + ) + elif row.qc_quarters is not None or row.quarterly_wages is not None: + raise InvalidFamilyInput( + "Post1977 uses annual earnings or QC count" + ) + if year >= 1978 and row.agricultural_wages is not None: + raise InvalidFamilyInput( + "Post1977 agricultural wages belong in wages" + ) + cutoff = min( + _qid(month), + _qid(person.death_date) if person.death_date else _qid(month), + _qid(coverage_end_month) if coverage_end_month else _qid(month), + ) + if row.qc_quarters is not None: + if any( + flag and not _qid(person.birth_date) <= year * 4 + i <= cutoff + for i, flag in enumerate(row.qc_quarters) + ): + raise InvalidFamilyInput( + "Quarterly QCs declared after coverage ends" + ) + if row.quarterly_wages is not None: + if any( + value and not _qid(person.birth_date) <= year * 4 + i <= cutoff + for i, value in enumerate(row.quarterly_wages) + ): + raise InvalidFamilyInput( + "Quarterly earnings declared after coverage ends" + ) + + +def _coverage_checks(person, years, month, credits): + if credits: + _refuse( + InsuredUnsupportedReason.TOTALIZATION, + "Foreign coverage is not implemented", + ) + for condition in sorted(person.conditions, key=lambda c: c.value): + _refuse(InsuredUnsupportedReason[condition.name], condition.value) + if person.alien_worker and ( + person.ssn_never_assigned + or person.ssn_assignment_date >= date(2004, 1, 1) + ): + _refuse( + InsuredUnsupportedReason.ALIEN_WORKER, + "SSPA211 additional alien-worker facts", + ) + if month < date(1968, 1, 1): + _refuse( + InsuredUnsupportedReason.HISTORICAL_ENTITLEMENT, + "Historical entitlement amendments", + ) + if person.statutory_blindness and month < date(1973, 1, 1): + _refuse( + InsuredUnsupportedReason.HISTORICAL_BLINDNESS, + "Pre1973 blindness tests", + ) + if any( + p.special_insured for p in person.prior_disability_periods + ) and month < date(1983, 5, 1): + _refuse( + InsuredUnsupportedReason.HISTORICAL_SUBSEQUENT, + "Pre1983 subsequent-period amendments", + ) + for year, row in years.items(): + if ( + year > 2027 + and row.provenance is not EarningsProvenance.UNKNOWN + and row.qc_count is None + ): + _refuse( + InsuredUnsupportedReason.QC_YEAR, + f"No captured QC increment for {year}", + ) + + +def _credits(year, row, upper): + if row.provenance is EarningsProvenance.UNKNOWN: + return (), 4 if upper else 0 + if row.qc_count is not None: + return (), row.qc_count + if row.qc_quarters is not None: + return ( + tuple( + year * 4 + i for i, flag in enumerate(row.qc_quarters) if flag + ), + 0, + ) + if year >= 1978: + return (), _post1977_qc_count( + year, row.wages or Fraction(0), row.self_employment or Fraction(0) + ) + try: + return _pre1978_qc_credits( + year, + row.quarterly_wages or (Fraction(0),) * 4, + row.self_employment or Fraction(0), + row.agricultural_wages or Fraction(0), + ) + except _UnsupportedQC as error: + _refuse(InsuredUnsupportedReason(error.reason), str(error)) + + +def _world( + person, + credits, + qid, + exit_month, + use_periods, + *, + include_zero=False, + prior_before=None, +): + periods = ( + tuple( + (_qid(p.start), _qid(p.end)) + for p in person.prior_disability_periods + if prior_before is None or p.end < prior_before + ) + if use_periods + else () + ) + rows = {} + for year, (fixed, flexible) in credits.items(): + if not include_zero and not fixed and not flexible: + continue + allowed = _allowed_quarters( + year, + through_quarter=qid, + death_quarter=( + _qid(person.death_date) if person.death_date else None + ), + coverage_end_quarter=_qid(exit_month) if exit_month else None, + disability_periods=periods, + ) + allowed = tuple(q for q in allowed if q >= _qid(person.birth_date)) + rows[year] = (fixed, flexible, allowed) + return rows, periods + + +def _boundary_variants(rows, periods): + years = sorted({q // 4 for pair in periods for q in pair} & rows.keys()) + options = [_assignment_candidates(*rows[y]) for y in years] + if prod(map(len, options)) > 4096: + _refuse( + InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, + "More than4096 boundary assignments", + ) + for choices in product(*options): + yield dict(zip(years, choices, strict=True)) + + +def _window(end, length, periods, boundary): + chosen = {q for quarters in boundary.values() for q in quarters} + answer = [] + qid = end + while len(answer) < length: + if not any(a <= qid <= b and qid not in chosen for a, b in periods): + answer.append(qid) + qid -= 1 + return tuple(reversed(answer)) + + +def _assignment(rows, window, boundary): + return tuple( + sorted( + q + for year, row in rows.items() + for q in ( + boundary[year] + if year in boundary + else _assign_qcs(*row, window=window) + ) + ) + ) + + +def _witness(person, credits, at, exit_month, kind, *, onset=True): + end = _qid(at) + best = None + # CFR404.130(f): consider all prior periods or disregard all, favorably. + for use_periods in ( + (True, False) if person.prior_disability_periods else (True,) + ): + prior_before = at if kind is InsuredTest.CURRENTLY else None + rows, periods = _world( + person, + credits, + end, + exit_month, + use_periods, + prior_before=prior_before, + ) + dates = ( + tuple( + (p.start, p.end) + for p in person.prior_disability_periods + if prior_before is None or p.end < prior_before + ) + if use_periods + else () + ) + fully_required = _requirement( + person, + at, + dates, + onset=onset, + for_disability=kind is InsuredTest.DISABILITY, + ) + for boundary in _boundary_variants(rows, periods): + full_assignment = _assignment(rows, (), boundary) + fully = len(full_assignment) >= fully_required + if ( + kind is InsuredTest.FULLY + or person.statutory_blindness + and kind is InsuredTest.DISABILITY + ): + candidates = [ + ( + tuple( + range( + max(1937, person.birth_date.year) * 4, end + 1 + ) + ), + fully_required, + ( + "fully" + if kind is InsuredTest.FULLY + else "blindness_fully_only" + ), + ) + ] + elif kind is InsuredTest.CURRENTLY: + candidates = [ + ( + _window(end, 13, periods, boundary), + 6, + "currently_6_of_13", + ) + ] + else: + candidates = [ + ( + _window(end, 40, periods, boundary), + 20, + "disability_20_of_40", + ) + ] + young = end < _qid(_attain(person.birth_date, 31)) + subsequent = any( + p.special_insured for p in person.prior_disability_periods + ) + if young or subsequent: + first = max( + 1937 * 4, _qid(_attain(person.birth_date, 21)) + 1 + ) + chosen = set(full_assignment) + elapsed = tuple( + q + for q in range(first, end + 1) + if not any( + a <= q <= b and q not in chosen for a, b in periods + ) + ) + if len(elapsed) < 12: + window, required = ( + _window(end, 12, periods, boundary), + 6, + ) + elif len(elapsed) > 40: + window, required = elapsed[-40:], 20 + else: + window, required = elapsed, max(6, len(elapsed) // 2) + candidates.append( + ( + window, + required, + ( + "subsequent_special" + if subsequent and not young + else "under31_special" + ), + ) + ) + for window, required, rule in candidates: + assignment = _assignment(rows, window, boundary) + count = len(set(assignment) & set(window)) + insured = count >= required and ( + fully if kind is InsuredTest.DISABILITY else True + ) + score = (insured, count - required, count, rule) + candidate = ( + insured, + count, + required, + window, + assignment, + rule, + fully_required, + len(full_assignment), + ) + if best is None or score > best[0]: + best = score, candidate + return best[1] + + +def _fra_quarter(person): + cohort = (person.birth_date - timedelta(days=1)).year + months = 780 + if 1938 <= cohort <= 1942: + months += (cohort - 1937) * 2 + elif 1943 <= cohort <= 1954: + months = 792 + elif 1955 <= cohort <= 1959: + months = 792 + (cohort - 1954) * 2 + elif cohort >= 1960: + months = 804 + index = person.birth_date.year * 12 + person.birth_date.month - 1 + months + year, month = divmod(index, 12) + day = min(person.birth_date.day, calendar.monthrange(year, month + 1)[1]) + return _qid(date(year, month + 1, day) - timedelta(days=1)) + + +def _last_insured(person, credits, month, exit_month): + last = None + if sum(len(fixed) + flexible for fixed, flexible in credits.values()) < 6: + return None, False + cap = min(_qid(month), _fra_quarter(person) - 1) + if person.death_date is not None: + cap = min(cap, _qid(person.death_date)) + # Without an exit declaration future work is not assumed zero. This is + # a last-insured-through-query value, with explicit right censoring. + if exit_month is not None and exit_month <= month: + cap = _fra_quarter(person) - 1 + if person.death_date is not None: + cap = min(cap, _qid(person.death_date)) + credited_years = [ + y for y, (fixed, flex) in credits.items() if fixed or flex + ] + start = max(min(credited_years) * 4, _qid(person.birth_date)) + if not person.statutory_blindness and not person.prior_disability_periods: + cap = min(cap, max(credited_years) * 4 + 3 + 39) + for qid in range(cap, start - 1, -1): + at = _qdate(qid) + # DLI asks potential onset in each quarter, not the declared onset. + if _witness( + person, + credits, + at, + exit_month, + InsuredTest.DISABILITY, + onset=False, + )[0]: + last = _qend(qid) + break + censored = ( + (exit_month is None or exit_month > month) + and cap == _qid(month) + and last == _qend(cap) + ) + return last, censored + + +@_validated_entry +def insured_status( + person: Person, + years: Mapping[int, CoverageYear], + month: date, + *, + test: InsuredTest = InsuredTest.ALL, + coverage_end_month: date | None = None, + totalization_credits: tuple[str, ...] = (), +) -> InsuredStatus: + """Decide a declared person-month; uncertain status is a retained refusal. + + B6a calls with test=FULLY. OP8(d)/OP12 use the same declaration and + optional exit month. No entry date, imputation, or zero default exists. + DLI is through this query, explicitly censored, unless exit freezes work. + """ + _validate_history( + person, years, month, coverage_end_month, totalization_credits + ) + _coverage_checks(person, years, month, totalization_credits) + lower = {y: _credits(y, row, False) for y, row in sorted(years.items())} + upper = {y: _credits(y, row, True) for y, row in sorted(years.items())} + unknown = tuple( + y + for y, row in sorted(years.items()) + if row.provenance is EarningsProvenance.UNKNOWN + ) + decisions = {} + for kind in ( + InsuredTest.FULLY, + InsuredTest.CURRENTLY, + InsuredTest.DISABILITY, + ): + decisions[kind] = None + if test not in (InsuredTest.ALL, kind): + continue + at = month + if ( + kind is InsuredTest.DISABILITY + and person.disability_onset is not None + and not person.statutory_blindness + ): + at = person.disability_onset + events = [at] + if kind is InsuredTest.CURRENTLY: + events = [ + event + for event in ( + person.death_date, + person.rib_entitlement_month, + person.dib_entitlement_month, + ) + if event is not None and event.replace(day=1) <= month + ] or [month] + lo = max( + ( + _witness(person, lower, event, coverage_end_month, kind) + for event in events + ), + key=lambda witness: (witness[0], witness[1]), + ) + hi = ( + max( + ( + _witness(person, upper, event, coverage_end_month, kind) + for event in events + ), + key=lambda witness: (witness[0], witness[1]), + ) + if unknown + else lo + ) + if lo[0] != hi[0]: + _refuse( + InsuredUnsupportedReason.UNKNOWN_EARNINGS, + f"{kind.value} differs across unknown years {unknown}", + ) + decisions[kind] = _computed( + StatusDecision, + lo[0], + lo[1], + hi[1], + lo[2], + lo[3], + lo[4], + lo[5], + hi[2], + hi[3], + hi[4], + hi[5], + lo[6], + hi[6], + lo[7], + hi[7], + ) + dli = None + if test in (InsuredTest.ALL, InsuredTest.DISABILITY): + lo_date, lo_censored = _last_insured( + person, lower, month, coverage_end_month + ) + hi_date, hi_censored = ( + _last_insured(person, upper, month, coverage_end_month) + if unknown + else (lo_date, lo_censored) + ) + dli = _computed(DLIRange, lo_date, hi_date, lo_censored or hi_censored) + lo_rows, _ = _world( + person, lower, _qid(month), coverage_end_month, True, include_zero=True + ) + hi_rows, _ = _world( + person, upper, _qid(month), coverage_end_month, True, include_zero=True + ) + assigned = {y: _assign_qcs(*row) for y, row in lo_rows.items()} + return _computed( + InsuredStatus, + VERSION, + month, + decisions[InsuredTest.FULLY], + decisions[InsuredTest.CURRENTLY], + decisions[InsuredTest.DISABILITY], + dli, + MappingProxyType( + { + y: (len(assigned[y]), len(_assign_qcs(*hi_rows[y]))) + for y in lo_rows + } + ), + MappingProxyType(assigned), + unknown, + MappingProxyType( + { + y: row.convention_id + for y, row in sorted(years.items()) + if row.provenance is EarningsProvenance.CONVENTION_FILLED + } + ), + bool(unknown), + ) + + +@_sealed_result +@dataclass(frozen=True) +class InsuredOutcome(_SealedOutcome): + key: str + weight: Fraction + result: InsuredStatus | None + unsupported: FamilyConfigurationUnsupported | None + + def __post_init__(self): + _check_evaluation_inputs(self.key, self.weight, lambda: None) + if self.result is not None: + _checked_result(self.result, InsuredStatus) + if self.unsupported is not None: + _check_refusal(self.unsupported) + if (self.result is None) == (self.unsupported is None): + raise InvalidFamilyInput( + "Exactly one insured result/refusal required" + ) + + @property + def supported(self) -> bool: + _check_seal(self) + return self.result is not None + + +@_validated_entry +def evaluate_insured_status( + key: str, weight: Fraction, compute: Callable[[], InsuredStatus] +) -> InsuredOutcome: + """Keep every coverage refusal in count_family_outcomes' denominator.""" + _check_evaluation_inputs(key, weight, compute) + try: + result = compute() + except FamilyConfigurationUnsupported as error: + return _computed(InsuredOutcome, key, weight, None, error) + _checked_result(result, InsuredStatus) + return _computed(InsuredOutcome, key, weight, result, None) diff --git a/tests/data/track_b/insured_status_examples.yaml b/tests/data/track_b/insured_status_examples.yaml new file mode 100644 index 000000000..7b67cb5ab --- /dev/null +++ b/tests/data/track_b/insured_status_examples.yaml @@ -0,0 +1,864 @@ +schema_version: 1 +verification_class: statutory_conformance +admitted_scope: Published statutory worked cases and invented declarations only; + no population, behavioral or forecast claim. A refused or missing-attachment entry + is an inventory item, not a reproduced computation. +examples: +- id: poms_106_deemed + source: poms_rs_00301_106 + quotes: + - NH's coverage begins 01/01/84. + - 04/01/85 + - '6' + expected: + coverage_start: '1984-01-01' + first_insured: '1985-04-01' + required_qcs: 6 + coverage: refused + note: Deemed nonprofit coverage is a named unsupported configuration. + refusal_reason: deemed_fully_insured_unsupported +- id: poms_120_guinness + source: poms_rs_00301_120 + quotes: + - Guinness T. Lis became disabled on 12/15/77. + - 20 quarters of coverage in the 40-quarter period ending with the 12/77 quarter + - 7/ 10 /88 + - 2/87 + - 17th + expected: + onset: '1977-12-15' + recent_qcs: 20 + window_quarters: 40 + filing: '1988-07-10' + waiting_month: 1987-02 + coverage: computed + note: Source asserts fully insured without DOB or detailed quarters. Test supplies + explicitly invented birth/earnings completion satisfying that assertion and + reproduces protection of onset insurance through the later waiting month; it + does not adjudicate the application. + test_node: tests/test_track_b_insured_status.py::test_guinness_lis_poms_120_freeze_protects_onset_status +- id: poms_122_military_freeze + source: poms_rs_00301_122 + quotes: + - from 14 to 8 + - only 7 QCs + - Cash benefits are not payable. + expected: + ordinary_requirement: 14 + freeze_requirement: 8 + nonmilitary_qcs: 7 + cash_insured: false + coverage: refused + note: Railroad and military credits are named unsupported inputs. + refusal_reason: military_credits_unsupported +- id: poms_140_fred + source: poms_rs_00301_140 + quotes: + - 5/13/58 + - 1/15/88 + - 35 calendar quarters + - 34 quarters + - 17 QC's + - 7/1/79 + expected: + birth: '1958-05-13' + onset: '1988-01-15' + elapsed_quarters: 35 + required_qcs: 17 + coverage: computed + test_node: tests/test_track_b_insured_status.py::test_fred_brown_35_quarters_require_17_poms_140_example_1 +- id: poms_140_sam + source: poms_rs_00301_140 + quotes: + - 8/20/61 + - 4/12/84 + - seven quarters + - 6 QC's + - 9/81 through 6/84 + expected: + birth: '1961-08-20' + onset: '1984-04-12' + elapsed_quarters: 7 + window_start: 1981-Q3 + window_end: 1984-Q2 + required_qcs: 6 + coverage: computed + test_node: tests/test_track_b_insured_status.py::test_sam_white_6_in_12_poms_140_example_2 +- id: poms_140_mary_met + source: poms_rs_00301_140 + quotes: + - 11/15/64 + - 8/30/85 + - 1984 CCCC + - 1985 CCNN + - Mary has 6 QC's in this 12 quarter period and meets insured status. + expected: + birth: '1964-11-15' + onset: '1985-08-30' + year_qcs: + 1982: 0 + 1983: 0 + 1984: 4 + 1985: 2 + required_qcs: 6 + insured: true + coverage: computed + test_node: tests/test_track_b_insured_status.py::test_mary_smith_special_window_poms_140_examples_3_to_5 +- id: poms_140_mary_not_met + source: poms_rs_00301_140 + quotes: + - 1981 CCCC + - 1982 CNNN + - 1983 CNNN + - 1984 CCCN + - 1985 NNNN + - Mary is not insured. + expected: + birth: '1964-11-15' + onset: '1985-08-30' + year_qcs: + 1981: 4 + 1982: 1 + 1983: 1 + 1984: 3 + 1985: 0 + required_qcs: 6 + insured: false + coverage: computed + test_node: tests/test_track_b_insured_status.py::test_mary_smith_special_window_poms_140_examples_3_to_5 +- id: poms_140_mary_moveable + source: poms_rs_00301_140 + quotes: + - 1982 CCCN + - 1983 NNNN + - 1984 CCCC + - 1985 CNNN + - Mary has 6 QC's in the 12-QTR period + expected: + birth: '1964-11-15' + onset: '1985-08-30' + year_qcs: + 1982: 3 + 1983: 0 + 1984: 4 + 1985: 1 + required_qcs: 6 + insured: true + coverage: computed + test_node: tests/test_track_b_insured_status.py::test_mary_smith_special_window_poms_140_examples_3_to_5 +- id: poms_140_joseph + source: poms_rs_00301_140 + quotes: + - 9/16/56 + - 2/3/81 + - 14 QTRS + - 7 QC's + - 2/14/84 + - 18 QC's + - 9 QTRs + expected: + birth: '1956-09-16' + first_onset: '1981-02-03' + onset: '1984-02-14' + first_elapsed: 14 + first_required: 7 + second_elapsed: 18 + second_required: 9 + insured: true + coverage: source_rule_divergence + note: Published 18-quarter/9-QC requirement excludes both qualifying endpoint + quarters; statutory endpoint counting yields 20/10. Both answers insure the + record. Kept side by side for review. + implemented: + elapsed_quarters: 20 + required_qcs: 10 + available_qcs: 16 + insured: true + test_node: tests/test_track_b_insured_status.py::test_joseph_subsequent_poms_140_example_6_endpoint_erratum +- id: poms_140_jane + source: poms_rs_00301_140 + quotes: + - 3/16/67 + - 3/29/88 + - 12/3/90 + - Jane has 6 QCs in the 12 -QTR period + expected: + birth: '1967-03-16' + first_onset: '1988-03-29' + onset: '1990-12-03' + required_qcs: 6 + insured: true + coverage: computed + test_node: tests/test_track_b_insured_status.py::test_subsequent_under31_poms_140_examples_7_and_8 +- id: poms_140_ralph + source: poms_rs_00301_140 + quotes: + - 4/12/67 + - 2/16/88 + - 3/16/97 + - 25 QCs + - '24' + - 12 QC's + expected: + birth: '1967-04-12' + first_onset: '1988-02-16' + onset: '1997-03-16' + elapsed_quarters: 25 + required_qcs: 12 + insured: true + coverage: computed + test_node: tests/test_track_b_insured_status.py::test_subsequent_under31_poms_140_examples_7_and_8 +- id: poms_140_sam_subsequent + source: poms_rs_00301_140 + quotes: + - 2/16/64 + - 12/16/85 + - 5/16/93 + - 17 QC's + - 8 QC's + - 7 QC's + - insured as of the 12/93 quarter + expected: + birth: '1964-02-16' + first_onset: '1985-12-16' + onset: '1993-05-16' + elapsed_quarters: 17 + required_qcs: 8 + observed_qcs: 7 + insured: false + later_insured: 1993-Q4 + coverage: source_rule_divergence + note: Source uses freeze and says not insured. CFR 404.130(f) requires disregarding + the entire prior freeze when advantageous; the record then has 20 QCs in 40 + quarters and is insured. Kept side by side for review. + implemented: + window_quarters: 40 + required_qcs: 20 + available_qcs: 20 + insured: true + test_node: tests/test_track_b_insured_status.py::test_sam_subsequent_poms_140_example_9_favorable_disregard_erratum +- id: poms_147_mary + source: poms_rs_00301_147 + quotes: + - 4/16/50 + - 5/16/75 + - 16 QTRs + - 8 QCs + - 11/2/82 + - 32 QTRs + - 16 QC's + expected: + birth: '1950-04-16' + first_onset: '1975-05-16' + onset: '1982-11-02' + first_required: 8 + elapsed_quarters: 32 + required_qcs: 16 + insured: true + coverage: computed + test_node: tests/test_track_b_insured_status.py::test_subsequent_over31_poms_147_examples +- id: poms_147_john + source: poms_rs_00301_147 + quotes: + - 7/16/40 + - 3/4/68 + - 26 QTRs + - 13 QC's + - 2/11/83 + - 33 QTRs + - 16 QC's + expected: + birth: '1940-07-16' + first_onset: '1968-03-04' + onset: '1983-02-11' + first_required: 13 + elapsed_quarters: 33 + required_qcs: 16 + insured: true + coverage: computed + test_node: tests/test_track_b_insured_status.py::test_subsequent_over31_poms_147_examples + note: Source says requires and has 16; the complete record has 18 qualifying QCs. + Its parenthetical says two additional QCs would reach 20/40, confirming 18. + The requirement16 and insured disposition reproduce exactly. +- id: poms_147_frank + source: poms_rs_00301_147 + quotes: + - 7/14/45 + - 12/13/70 + - 17 QTRs + - 8 QC's + - 2/11/83 + - 33 QTRs + - 16 QC's + - Their claim must be denied. + expected: + birth: '1945-07-14' + first_onset: '1970-12-13' + onset: '1983-02-11' + first_required: 8 + elapsed_quarters: 33 + required_qcs: 16 + observed_qcs: 8 + insured: false + coverage: source_rule_divergence + note: Published 33/16/8 treats 1978 annual QC as fixed Q1. Favorable reassignment + to PPD endpoint1978Q4 yields34/17/9; both deny insured status. + test_node: tests/test_track_b_insured_status.py::test_subsequent_over31_poms_147_examples + implemented: + elapsed_quarters: 34 + required_qcs: 17 + available_qcs: 9 + insured: false +- id: poms_148_dli + source: poms_rs_00301_148 + quotes: + - 3/09/54 + - 1973 CCNN + - 1975 CCCC + - 1976 CCCC + - 1980 CCNN + - 1981 CCNN + - 1982 CCCC + - 1985 CCCC + - 1986 CCCC + - 1987 CCNN + - 1988 CCNN + - 6/30/90 + - 14 QC's + - 30 QC's + expected: + birth: '1954-03-09' + year_qcs: + 1973: 2 + 1974: 0 + 1975: 4 + 1976: 4 + 1977: 0 + 1978: 0 + 1979: 0 + 1980: 2 + 1981: 2 + 1982: 4 + 1983: 0 + 1984: 0 + 1985: 4 + 1986: 4 + 1987: 2 + 1988: 2 + 1989: 0 + 1990: 0 + dli: '1990-06-30' + fully_required: 14 + total_qcs: 30 + coverage: computed + test_node: tests/test_track_b_insured_status.py::test_dli_1990_june_poms_148_example +- id: poms_148_fra + source: poms_rs_00301_148 + quotes: + - FRA attainment is 11/2019 + - DLI is 9/30/2019 + expected: + fra_month: 2019-11 + dli: '2019-09-30' + coverage: computed + test_node: tests/test_track_b_insured_status.py::test_dli_fra_cap_poms_148_november_2019 +- id: poms_150_calvin + source: poms_rs_00301_150 + quotes: + - 7/12/57 + - 1977 NNCC + - 1982 CNNN + - 1983 CNNN + - 1985 CNNN + - 1986 CCNN + - 03/86 quarter + - seven QCs + - 04/01/1986 + expected: + birth: '1957-07-12' + blind_from_birth: true + year_qcs: + 1977: 2 + 1982: 1 + 1983: 1 + 1985: 1 + 1986: 2 + required_qcs: 7 + first_insured: '1986-04-01' + coverage: computed + test_node: tests/test_track_b_insured_status.py::test_calvin_hill_blind_clock_poms_150_example +- id: poms_160_blind_freeze + source: poms_rs_00301_160 + quotes: + - A blind person would not meet the insured status requirements + - could not qualify for Medicare. + expected: + medicare_eligible: false + coverage: refused + note: Medicare-qualified government credits and Medicare entitlement are unsupported. + refusal_reason: medicare_government_employment_unsupported +- id: poms_220_ann_fiscal + source: poms_rs_00301_220 + quotes: + - $12,000 + - 10/01/87 + - 09/30/88 + - $3,000 (3/12 x 12,000) + - $9,000 SEI. (9/12 x 12,000) + expected: + sei: '12000' + '1987': '3000' + '1988': '9000' + coverage: computed + test_node: tests/test_track_b_insured_status_qc.py::test_rs00301_220_ann_calendar_year_sei_allocation + execution_scope: allocation_helper + public_refusal_reason: fiscal_taxable_year_unsupported +- id: poms_230_henry_reassignment + source: poms_rs_00301_230 + quotes: + - 05/23/1948 + - May 2010 + - $1,500 + - first quarter of 2010 + expected: + birth: '1948-05-23' + 2010_wages: '1500' + 2010_qcs: 1 + assignment: 2010-Q1 + coverage: computed + test_node: tests/test_track_b_insured_status_qc.py::test_rs00301_230_henry_and_325_john_retroactive_assignment +- id: poms_315_simplified + source: poms_rs_00301_315 + quotes: + - 09/08/1926 + - 09/1991 + - 37 QCs + - 23 QCs + - $5,700 divided by $400 = 14 + - $5,500 + - 13 QCs + expected: + birth: '1926-09-08' + post1950_qcs: 23 + required_qcs: 37 + pre1951_wages: '5700' + simplified_qcs: 14 + lower_wages: '5500' + lower_qcs: 13 + coverage: refused + note: Simplified pre-1951 aggregate credits require the named special credit condition. + refusal_reason: simplified_pre1951_unsupported +- id: poms_315_retroactive + source: poms_rs_00301_315 + quotes: + - 37 QCs with 14 QCs + - 37th QC in the 09/1991 quarter + - If the number of QCs exceeds 14 + expected: + required_qcs: 37 + allocated_qcs: 14 + last_qc: 1991-Q3 + coverage: refused + note: Retroactive claims and simplified pre-1951 aggregates are outside the evaluator. + refusal_reason: simplified_pre1951_unsupported +- id: poms_320_jane_agricultural + source: poms_rs_00301_320 + quotes: + - $101 + - $150 + - $90 + - $50 + - $59 + - $160 + - 20 different days + - $400 + - four QCs + - 12/1973 QC + - 09/1973 based on nonagricultural wages + - 06/1973 and 03/1973 + expected: + year: 1973 + agricultural_wages: '400' + quarterly_wages: + - '0' + - '0' + - '50' + - '0' + qcs: 4 + coverage: computed + test_node: tests/test_track_b_insured_status_qc.py::test_rs00301_320_jane_agricultural_example +- id: poms_325_john_reassignment + source: poms_rs_00301_325 + quotes: + - 03/2010 + - $1200 + - 11/2010 + - 01/2010 + expected: + year: 2010 + agricultural_wages: '1200' + qcs: 1 + assignment: 2010-Q1 + coverage: computed + test_node: tests/test_track_b_insured_status_qc.py::test_rs00301_230_henry_and_325_john_retroactive_assignment +- id: poms_340_john_fiscal + source: poms_rs_00301_340 + quotes: + - $10,800 + - 03/31/1974 + - 03/1974 - $2,700 + - 12/1973 - $2,700 + - 09/1973 - $2,700 + - 06/1973 - $2,700 + expected: + sei: '10800' + fiscal_end: '1974-03-31' + allocation: + - '2700' + - '2700' + - '2700' + - '2700' + coverage: computed + test_node: tests/test_track_b_insured_status_qc.py::test_rs00301_340_john_fiscal_sei_allocation + execution_scope: allocation_helper + public_refusal_reason: fiscal_taxable_year_unsupported +- id: poms_340_jane_short_erratum + source: poms_rs_00301_340 + quotes: + - 09/01/1973 + - 01/03/1974 + - $10,900 + - $3,600 + - 03/1974, 12/1973 and 09/1973 + expected: + sei: '10900' + published_allocation: + - '3600' + - '3600' + - '3600' + published_total: '10800' + literal_covered_sei_allocation: + - 10900/3 + - 10900/3 + - 10900/3 + unstated_ceiling: '10800' + ceiling_reading_allocation: + - '3600' + - '3600' + - '3600' + allocated_earnings_difference: '100' + qcs_both_readings: 3 + coverage: source_ambiguity + note: The capture labels10900 as SEI but prints3600 for each of3 quarters. Literal + already-covered SEI gives10900/3. An unstated10800 ceiling for TYbeginning1973, + from RS00301.345 and Act213(a)(2)(B)(iii), explains3600 each if10900 meant net + earnings before the ceiling. Both readings are executed; neither an arithmetic + erratum nor the omitted ceiling is established by the capture. Both yield3QCs + and differ by100 in allocated earnings. Private helper consumes already-covered + SEI; public short taxable years remain refused. + test_node: tests/test_track_b_insured_status_qc.py::test_rs00301_340_short_year_source_erratum_is_not_imitated + execution_scope: allocation_helper + public_refusal_reason: short_taxable_year_unsupported +- id: poms_345_john_four_gift + source: poms_rs_00301_345 + quotes: + - $2,700 + - $10,600 + - 06/30/1974 + - $8,100 + - $10,800 + - two QCs in 1973 and two in 1974 + expected: + wages: '2700' + net_se: '10600' + sei: '8100' + combined: '10800' + qcs_by_year: + 1973: 2 + 1974: 2 + coverage: computed + test_node: tests/test_track_b_insured_status_qc.py::test_rs00301_345_fiscal_gift_credit_examples + execution_scope: allocation_helper + public_refusal_reason: fiscal_taxable_year_unsupported +- id: poms_345_jane_five_gift + source: poms_rs_00301_345 + quotes: + - $10,800 + - 05/31/1974 + - five QCs including one for the second quarter of 1973 + expected: + sei: '10800' + fiscal_end: '1974-05-31' + qcs: 5 + qcs_by_year: + 1973: 3 + 1974: 2 + coverage: computed + test_node: tests/test_track_b_insured_status_qc.py::test_rs00301_345_fiscal_gift_credit_examples + execution_scope: allocation_helper + public_refusal_reason: fiscal_taxable_year_unsupported +- id: poms_345_public_combined_gift + source: poms_rs_00301_345 + quotes: + - $10,620 + - 05/31/1974 + - $180 + - $10,800 + - five QCs based on their combined wages and SEI + expected: + sei: '10620' + wages: '180' + combined: '10800' + qcs: 5 + coverage: computed + test_node: tests/test_track_b_insured_status_qc.py::test_rs00301_345_fiscal_gift_credit_examples + execution_scope: allocation_helper + public_refusal_reason: fiscal_taxable_year_unsupported +- id: cfr_102_age_attainment + source: ecfr_20cfr404_subpart_b + quotes: + - July 1, 1979 + - June 30, 1979 + expected: + birth: '1917-07-01' + age: 62 + attainment: '1979-06-30' + coverage: computed + test_node: tests/test_track_b_insured_status.py::test_age_attainment_day_before_birthday_cfr_404_102_example +- id: cfr_110_disability_years + source: ecfr_20cfr404_subpart_b + quotes: + - December 5, 1975 through January 31, 1977 + - 1975, 1976 and 1977 + expected: + period_start: '1975-12-05' + period_end: '1977-01-31' + excluded_years: + - 1975 + - 1976 + - 1977 + coverage: computed + test_node: tests/test_track_b_insured_status.py::test_fully_requirement_excludes_partial_disability_years_cfr_example +- id: cfr_143_two_increments + source: ecfr_20cfr404_subpart_b + quotes: + - more than twice, but less than 3 times + - only 2 QCs + expected: + earnings_multiple: 5/2 + qcs: 2 + coverage: computed + test_node: tests/test_track_b_insured_status_qc.py::test_cfr404_143_two_and_fraction_increments +- id: cfr_144_fiscal + source: ecfr_20cfr404_subpart_b + quotes: + - May 15, 1978 + - May 14, 1979 + - $1200 + - 7/12 ($700) + - 5/12 ($500) + expected: + sei: '1200' + '1978': '700' + '1979': '500' + coverage: computed + test_node: tests/test_track_b_insured_status_qc.py::test_cfr404_144_partial_month_taxable_year_example + execution_scope: allocation_helper + public_refusal_reason: fiscal_taxable_year_unsupported +- id: oact_2027_determination + source: ssa_oact_qc + quotes: + - $250 times 72,800.33 divided by 9,226.48 equals $1,972.59, which rounds to $1,970 + - $1,890 + expected: + base: '250' + nawi_1976: '9226.48' + nawi_2025: '72800.33' + rounded_cents: '1972.59' + amount: 1970 + prior_amount: 1890 + coverage: computed + test_node: tests/test_track_b_insured_status_qc.py::test_oact_2027_published_determination +- id: poms_250_chart + source: poms_rs_00301_250 + quotes: + - 2010 – 2011 $1,120 $4,480 + - 2026 $1,890 $7,560 + - 1978 $250 $1000 + expected: + first_year: 1978 + last_year: 2026 + year_count: 49 + coverage: table_differential + test_node: tests/test_track_b_insured_status_sources.py::test_poms_and_oact_qc_charts_agree_every_shared_year +- id: cfr_115_cohort_chart + source: ecfr_20cfr404_subpart_b + quotes: + - Jan. 1, 1893 or earlier + - Jan. 2, 1929 or later + expected: + first_band: 1893-or-earlier + last_band: 1929-or-later + coverage: table_differential + test_node: tests/test_track_b_insured_status.py::test_fully_requirement_differential_cfr_404_115_every_captured_row +- id: poms_800_exhibit + source: poms_rs_00301_800 + quotes: + - Quarters of Coverage Requirements - Exhibit + - View In PDF + expected: {} + coverage: missing_attachment + note: Staged HTML links to two GIFs and a PDF; their bytes are not staged. CFR + 404.115 supplies an independent text cohort chart; do not claim the unavailable + RS 00301.800 exhibit is reproduced. +- id: poms_102_1_lucinda + source: poms_rs_00301_102 + quotes: + - 2/13/2004 + - 2/12/2005 + - 3/25/2005 + expected: + sspa_criterion_satisfied_or_exempt: true + coverage: refused + note: Alien-worker adjudicative facts are named unsupported inputs; this expected + value records the source conclusion, not an implementation result. + refusal_reason: alien_worker_sspa211_unsupported +- id: poms_102_2_john + source: poms_rs_00301_102 + quotes: + - 3/15/04 + - 3/20/04 + - John W. does not meet insured status + - The deceased worker was never assigned an SSN. + expected: + sspa_criterion_satisfied_or_exempt: false + coverage: refused + note: Alien-worker adjudicative facts are named unsupported inputs; this expected + value records the source conclusion, not an implementation result. + refusal_reason: alien_worker_sspa211_unsupported + test_node: tests/test_track_b_insured_status_sources.py::test_poms_102_never_assigned_ssn_is_a_named_refusal + refusal_input: + alien_worker: true + ssn_never_assigned: true +- id: poms_102_3_yelena + source: poms_rs_00301_102 + quotes: + - 11/02/2003 + - 12/31/2003 + - Yelena's SSN was assigned before 01/01/2004 + expected: + sspa_criterion_satisfied_or_exempt: true + coverage: administrative_inventory + note: SSN predates2004 and is exempt from the additional alien criterion. Source + gives no exact QC record; lawful-presence suspension and scrambled-earnings + adjudication are outside the module. This is a source inventory, not a refused + insured-status call. +- id: poms_102_4_gustav + source: poms_rs_00301_102 + quotes: + - 4/16/97 + - 3/13/04 + - 5/12/04 + - 5/14/04 + - 6/22/04 + expected: + sspa_criterion_satisfied_or_exempt: true + coverage: refused + note: Alien-worker adjudicative facts are named unsupported inputs; this expected + value records the source conclusion, not an implementation result. + refusal_reason: alien_worker_sspa211_unsupported +- id: poms_102_5_kismet + source: poms_rs_00301_102 + quotes: + - 03/22/05 + - Kismet meets the requirements of Section 211 of the SSPA. + - They have never been assigned an SSN, nor were they ever issued an SSN card + for work purposes. + expected: + sspa_criterion_satisfied_or_exempt: true + coverage: refused + note: Alien-worker adjudicative facts are named unsupported inputs; this expected + value records the source conclusion, not an implementation result. + refusal_reason: alien_worker_sspa211_unsupported + test_node: tests/test_track_b_insured_status_sources.py::test_poms_102_never_assigned_ssn_is_a_named_refusal + refusal_input: + alien_worker: true + ssn_never_assigned: true +- id: poms_102_6_rocky + source: poms_rs_00301_102 + quotes: + - February 2004 + - more than 40 QCs + - Rocky does not meet fully or currently insured status + - Rocky and Oksana were never assigned SSNs. + expected: + sspa_criterion_satisfied_or_exempt: false + coverage: refused + note: Alien-worker adjudicative facts are named unsupported inputs; this expected + value records the source conclusion, not an implementation result. + refusal_reason: alien_worker_sspa211_unsupported + test_node: tests/test_track_b_insured_status_sources.py::test_poms_102_never_assigned_ssn_is_a_named_refusal + refusal_input: + alien_worker: true + ssn_never_assigned: true +- id: poms_102_7_cyril + source: poms_rs_00301_102 + quotes: + - 6/15/04 + - Cyril meets the requirements of Section 211 of the SSPA. + - 40 QCs + - nor were they ever assigned an SSN. + expected: + sspa_criterion_satisfied_or_exempt: true + coverage: refused + note: Alien-worker adjudicative facts are named unsupported inputs; this expected + value records the source conclusion, not an implementation result. + refusal_reason: alien_worker_sspa211_unsupported + test_node: tests/test_track_b_insured_status_sources.py::test_poms_102_never_assigned_ssn_is_a_named_refusal + refusal_input: + alien_worker: true + ssn_never_assigned: true +- id: poms_102_8_catherine + source: poms_rs_00301_102 + quotes: + - 6/12/00 + - 4/15/04 + - 5/21/04 + - Catherine's SSN was first assigned before 1/1/2004 + expected: + sspa_criterion_satisfied_or_exempt: true + coverage: administrative_inventory + note: SSN predates2004 and is exempt from the additional alien criterion. Source + gives no exact QC record; lawful-presence suspension and scrambled-earnings + adjudication are outside the module. This is a source inventory, not a refused + insured-status call. +- id: poms_102_2_john_authorized_alternative + source: poms_rs_00301_102 + quotes: + - work authorization status at the time of their death + - would be met + expected: + sspa_criterion_satisfied: true + coverage: refused + note: Source alternative scenario; alien-worker adjudication is unsupported. + refusal_reason: alien_worker_sspa211_unsupported +source_findings: + poms_345_impossible_1975_interval: + source: poms_rs_00301_345 + quote: $14,100 in a TY beginning after 1975 and before 1975 + finding: Empty interval as printed; the preceding wage table lists $14,100 for + 1975. Calendar-year wage maximum uses that table. No fiscal-year interpretation + is silently inferred. + poms_102_conflicting_issue_dates: + source: poms_rs_00301_102 + quotes: + - 5/12/04 + - 5/14/04 + finding: Example 4 names two SSN issuance dates; both after the statutory threshold. + Alien adjudication is refused. + poms_340_possible_unstated_ceiling: + source: poms_rs_00301_345 + quote: $10,800 in a TY beginning after 1972 and before 1974; + finding: This ceiling could explain the short-taxable-year example in RS00301.340:10800/3=3600, + if printed10900 meant net earnings before the ceiling rather than already-covered + SEI. The capture does not state the cap step; both readings stay explicit. diff --git a/tests/data/track_b/insured_status_mutation_checks.json b/tests/data/track_b/insured_status_mutation_checks.json new file mode 100644 index 000000000..b9f0b2e67 --- /dev/null +++ b/tests/data/track_b/insured_status_mutation_checks.json @@ -0,0 +1,418 @@ +{ + "verification_class": "statutory_conformance", + "scope": "Invented and captured statutory cases only; no population, behavioral or forecast claim.", + "qc_mutations": [ + { + "name": "qc_cap_4_to_3", + "before": "return min(4, (wages + self_employment) // QC_AMOUNTS[year])", + "after": "return min(3, (wages + self_employment) // QC_AMOUNTS[year])", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary", + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1978]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1979]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1980]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1981]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1982]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1983]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1984]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1985]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1986]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1987]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1988]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1989]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1990]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1991]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1992]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1993]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1994]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1995]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1996]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1997]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1998]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1999]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2000]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2001]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2002]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2003]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2004]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2005]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2006]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2007]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2008]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2009]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2010]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2011]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2012]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2013]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2014]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2015]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2016]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2017]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2018]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2019]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2020]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2021]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2022]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2023]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2024]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2025]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2026]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2027]" + ], + "summary": [ + "50 failed, 150 passed in 15.27s" + ], + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/track-b-insured-psid", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/track-b-insured-epuf", + "PYTHONPATH": "$PWD/src:$PWD", + "PYTHONDONTWRITEBYTECODE": "1" + }, + "restored": true + }, + { + "name": "round_drop_half_tie", + "before": "rounded = ((indexed + 5) // 10) * 10", + "after": "rounded = ((indexed + 0) // 10) * 10", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_qc.py::test_qc_amount_ties_round_up", + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_qc.py::test_qc_amount_ties_round_up[delta1-260]", + "FAILED tests/test_track_b_insured_status_qc.py::test_qc_amount_ties_round_up[delta2-260]" + ], + "summary": [ + "2 failed, 1 passed in 6.57s" + ], + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/track-b-insured-psid", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/track-b-insured-epuf", + "PYTHONPATH": "$PWD/src:$PWD", + "PYTHONDONTWRITEBYTECODE": "1" + }, + "restored": true + }, + { + "name": "wage_50_inclusive_to_strict", + "before": "if wages >= 50", + "after": "if wages > 50", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary", + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1937]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1938]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1939]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1940]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1941]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1942]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1943]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1944]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1945]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1946]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1947]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1948]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1949]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1950]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1951]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1952]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1953]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1954]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1955]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1956]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1957]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1958]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1959]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1960]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1961]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1962]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1963]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1964]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1965]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1966]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1967]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1968]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1969]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1970]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1971]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1972]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1973]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1974]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1975]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1976]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1977]" + ], + "summary": [ + "41 failed in 16.30s" + ], + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/track-b-insured-psid", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/track-b-insured-epuf", + "PYTHONPATH": "$PWD/src:$PWD", + "PYTHONDONTWRITEBYTECODE": "1" + }, + "restored": true + }, + { + "name": "sei_400_inclusive_to_strict", + "before": "or self_employment >= 400", + "after": "or self_employment > 400", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary", + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1951]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1952]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1953]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1954]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1955]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1956]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1957]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1958]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1959]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1960]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1961]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1962]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1963]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1964]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1965]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1966]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1967]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1968]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1969]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1970]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1971]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1972]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1973]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1974]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1975]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1976]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1977]" + ], + "summary": [ + "27 failed in 9.66s" + ], + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/track-b-insured-psid", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/track-b-insured-epuf", + "PYTHONPATH": "$PWD/src:$PWD", + "PYTHONDONTWRITEBYTECODE": "1" + }, + "restored": true + }, + { + "name": "disability_exclude_first_endpoint", + "before": "start < quarter < end", + "after": "start <= quarter < end", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_qc.py::test_death_future_exit_and_disability_endpoint_exclusions", + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_qc.py::test_death_future_exit_and_disability_endpoint_exclusions" + ], + "summary": [ + "1 failed in 7.23s" + ], + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/track-b-insured-psid", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/track-b-insured-epuf", + "PYTHONPATH": "$PWD/src:$PWD", + "PYTHONDONTWRITEBYTECODE": "1" + }, + "restored": true + }, + { + "name": "assignment_maximize_to_minimize", + "before": "-len(target.intersection(candidate))", + "after": "len(target.intersection(candidate))", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_qc.py::test_rs00301_230_henry_and_325_john_retroactive_assignment", + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_qc.py::test_rs00301_230_henry_and_325_john_retroactive_assignment" + ], + "summary": [ + "1 failed in 6.27s" + ], + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/track-b-insured-psid", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/track-b-insured-epuf", + "PYTHONPATH": "$PWD/src:$PWD", + "PYTHONDONTWRITEBYTECODE": "1" + }, + "restored": true + }, + { + "name": "agricultural_increment_100_to_200", + "before": "agricultural_wages // 100", + "after": "agricultural_wages // 200", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_qc.py::test_rs00301_320_jane_agricultural_example", + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_qc.py::test_rs00301_320_jane_agricultural_example" + ], + "summary": [ + "1 failed in 5.11s" + ], + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/track-b-insured-psid", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/track-b-insured-epuf", + "PYTHONPATH": "$PWD/src:$PWD", + "PYTHONDONTWRITEBYTECODE": "1" + }, + "restored": true + }, + { + "name": "gift_maximum_inclusive_to_strict", + "before": "wages + self_employment >= _annual_wage_limit(year)", + "after": "wages + self_employment > _annual_wage_limit(year)", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs", + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1937-1950-3000]", + "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1951-1954-3600]", + "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1955-1958-4200]", + "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1959-1965-4800]", + "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1966-1967-6600]", + "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1968-1971-7800]", + "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1972-1972-9000]", + "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1973-1973-10800]", + "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1974-1974-13200]", + "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1975-1975-14100]", + "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1976-1976-15300]", + "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1977-1977-16500]" + ], + "summary": [ + "12 failed in 3.60s" + ], + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/track-b-insured-psid", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/track-b-insured-epuf", + "PYTHONPATH": "$PWD/src:$PWD", + "PYTHONDONTWRITEBYTECODE": "1" + }, + "restored": true + } + ], + "status_mutations": { + "file": "src/populace_dynamics/track_b/insured_status.py", + "sha256_before": "b6bf989787bd465e080a435d77a178cee9ef861535eac190ab7fca9bd1033fc8", + "mutations": [ + { + "name": "fully_minimum_6_to_5", + "before": "return min(40, max(6, elapsed))", + "after": "return min(40, max(5, elapsed))", + "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status.py -k test_fully_six_qcs_minimum", + "exit_code": 1, + "seconds": 49.08, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status.py::test_fully_six_qcs_minimum[5-False]", + "FAILED tests/test_track_b_insured_status.py::test_fully_six_qcs_minimum[6-True]" + ], + "output": "FF [100%]\n=================================== FAILURES ===================================\n_____________________ test_fully_six_qcs_minimum[5-False] ______________________\n\ncount = 5, expected = False\n\n @pytest.mark.parametrize(\"count,expected\", [(5, False), (6, True)])\n def test_fully_six_qcs_minimum(count, expected):\n person = i.Person(date(2000, 2, 2))\n result = compute(\n person,\n date(2026, 12, 1),\n {2025: 4, 2026: count - 4},\n test=i.InsuredTest.FULLY,\n )\n> assert result.fully.required == 6\nE AssertionError: assert 5 == 6\nE + where 5 = StatusDecision(insured=True, qc_count_lower=5, qc_count_upper=5, required=5, window=(8000, 8001, 8002, 8003, 8004, 800... 8101, 8102, 8103, 8104, 8105, 8106, 8107), upper_assigned_quarters=(8100, 8101, 8102, 8103, 8104), upper_rule='fully').required\nE + where StatusDecision(insured=True, qc_count_lower=5, qc_count_upper=5, required=5, window=(8000, 8001, 8002, 8003, 8004, 800... 8101, 8102, 8103, 8104, 8105, 8106, 8107), upper_assigned_quarters=(8100, 8101, 8102, 8103, 8104), upper_rule='fully') = InsuredStatus(version='track-b-insured-v1', month=datetime.date(2026, 12, 1), fully=StatusDecision(insured=True, qc_co...101, 8102, 8103), 2026: (8104,)}), unknown_years=(), convention_years=mappingproxy({}), decided_despite_unknowns=False).fully\n\ntests/test_track_b_insured_status.py:767: AssertionError\n______________________ test_fully_six_qcs_minimum[6-True] ______________________\n\ncount = 6, expected = True\n\n @pytest.mark.parametrize(\"count,expected\", [(5, False), (6, True)])\n def test_fully_six_qcs_minimum(count, expected):\n person = i.Person(date(2000, 2, 2))\n result = compute(\n person,\n date(2026, 12, 1),\n {2025: 4, 2026: count - 4},\n test=i.InsuredTest.FULLY,\n )\n> assert result.fully.required == 6\nE AssertionError: assert 5 == 6\nE + where 5 = StatusDecision(insured=True, qc_count_lower=6, qc_count_upper=6, required=5, window=(8000, 8001, 8002, 8003, 8004, 800... 8102, 8103, 8104, 8105, 8106, 8107), upper_assigned_quarters=(8100, 8101, 8102, 8103, 8104, 8105), upper_rule='fully').required\nE + where StatusDecision(insured=True, qc_count_lower=6, qc_count_upper=6, required=5, window=(8000, 8001, 8002, 8003, 8004, 800... 8102, 8103, 8104, 8105, 8106, 8107), upper_assigned_quarters=(8100, 8101, 8102, 8103, 8104, 8105), upper_rule='fully') = InsuredStatus(version='track-b-insured-v1', month=datetime.date(2026, 12, 1), fully=StatusDecision(insured=True, qc_co...8102, 8103), 2026: (8104, 8105)}), unknown_years=(), convention_years=mappingproxy({}), decided_despite_unknowns=False).fully\n\ntests/test_track_b_insured_status.py:767: AssertionError\n=========================== short test summary info ============================\nFAILED tests/test_track_b_insured_status.py::test_fully_six_qcs_minimum[5-False]\nFAILED tests/test_track_b_insured_status.py::test_fully_six_qcs_minimum[6-True]\n2 failed, 46 deselected in 23.71s\n", + "restored": true + }, + { + "name": "currently_requirement_6_to_5", + "before": "_window(end, 13, periods, boundary),\n 6,", + "after": "_window(end, 13, periods, boundary),\n 5,", + "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status.py -k test_currently_six_qcs_boundary", + "exit_code": 1, + "seconds": 46.04, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status.py::test_currently_six_qcs_boundary[5-False]", + "FAILED tests/test_track_b_insured_status.py::test_currently_six_qcs_boundary[6-True]" + ], + "output": "FF [100%]\n=================================== FAILURES ===================================\n___________________ test_currently_six_qcs_boundary[5-False] ___________________\n\ncount = 5, expected = False\n\n @pytest.mark.parametrize(\"count,expected\", [(5, False), (6, True)])\n def test_currently_six_qcs_boundary(count, expected):\n person = i.Person(date(1990, 2, 2))\n result = compute(\n person,\n date(2026, 12, 1),\n {2025: 4, 2026: count - 4},\n test=i.InsuredTest.CURRENTLY,\n )\n> assert result.currently.required == 6\nE AssertionError: assert 5 == 6\nE + where 5 = StatusDecision(insured=True, qc_count_lower=5, qc_count_upper=5, required=5, window=(8095, 8096, 8097, 8098, 8099, 810... 8103, 8104, 8105, 8106, 8107), upper_assigned_quarters=(8100, 8101, 8102, 8103, 8104), upper_rule='currently_6_of_13').required\nE + where StatusDecision(insured=True, qc_count_lower=5, qc_count_upper=5, required=5, window=(8095, 8096, 8097, 8098, 8099, 810... 8103, 8104, 8105, 8106, 8107), upper_assigned_quarters=(8100, 8101, 8102, 8103, 8104), upper_rule='currently_6_of_13') = InsuredStatus(version='track-b-insured-v1', month=datetime.date(2026, 12, 1), fully=None, currently=StatusDecision(ins...101, 8102, 8103), 2026: (8104,)}), unknown_years=(), convention_years=mappingproxy({}), decided_despite_unknowns=False).currently\n\ntests/test_track_b_insured_status.py:744: AssertionError\n___________________ test_currently_six_qcs_boundary[6-True] ____________________\n\ncount = 6, expected = True\n\n @pytest.mark.parametrize(\"count,expected\", [(5, False), (6, True)])\n def test_currently_six_qcs_boundary(count, expected):\n person = i.Person(date(1990, 2, 2))\n result = compute(\n person,\n date(2026, 12, 1),\n {2025: 4, 2026: count - 4},\n test=i.InsuredTest.CURRENTLY,\n )\n> assert result.currently.required == 6\nE AssertionError: assert 5 == 6\nE + where 5 = StatusDecision(insured=True, qc_count_lower=6, qc_count_upper=6, required=5, window=(8095, 8096, 8097, 8098, 8099, 810... 8104, 8105, 8106, 8107), upper_assigned_quarters=(8100, 8101, 8102, 8103, 8104, 8105), upper_rule='currently_6_of_13').required\nE + where StatusDecision(insured=True, qc_count_lower=6, qc_count_upper=6, required=5, window=(8095, 8096, 8097, 8098, 8099, 810... 8104, 8105, 8106, 8107), upper_assigned_quarters=(8100, 8101, 8102, 8103, 8104, 8105), upper_rule='currently_6_of_13') = InsuredStatus(version='track-b-insured-v1', month=datetime.date(2026, 12, 1), fully=None, currently=StatusDecision(ins...8102, 8103), 2026: (8104, 8105)}), unknown_years=(), convention_years=mappingproxy({}), decided_despite_unknowns=False).currently\n\ntests/test_track_b_insured_status.py:744: AssertionError\n=========================== short test summary info ============================\nFAILED tests/test_track_b_insured_status.py::test_currently_six_qcs_boundary[5-False]\nFAILED tests/test_track_b_insured_status.py::test_currently_six_qcs_boundary[6-True]\n2 failed, 46 deselected in 17.67s\n", + "restored": true + }, + { + "name": "regular_disability_20_to_19", + "before": "_window(end, 40, periods, boundary),\n 20,", + "after": "_window(end, 40, periods, boundary),\n 19,", + "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status.py -k test_disability_twenty_qcs_boundary", + "exit_code": 1, + "seconds": 75.26, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status.py::test_disability_twenty_qcs_boundary[19-False]", + "FAILED tests/test_track_b_insured_status.py::test_disability_twenty_qcs_boundary[20-True]" + ], + "output": "FF [100%]\n=================================== FAILURES ===================================\n________________ test_disability_twenty_qcs_boundary[19-False] _________________\n\ncount = 19, expected = False\n\n @pytest.mark.parametrize(\"count,expected\", [(19, False), (20, True)])\n def test_disability_twenty_qcs_boundary(count, expected):\n person = i.Person(date(1990, 2, 2))\n counts = {2021: 4, 2022: 4, 2023: 4, 2024: 4, 2025: count - 16}\n result = compute(person, date(2026, 12, 1), counts)\n assert result.fully.insured\n> assert result.disability.required == 20\nE AssertionError: assert 19 == 20\nE + where 19 = StatusDecision(insured=True, qc_count_lower=19, qc_count_upper=19, required=19, window=(8068, 8069, 8070, 8071, 8072, ... 8089, 8090, 8091, 8092, 8093, 8094, 8095, 8096, 8097, 8098, 8099, 8100, 8101, 8102), upper_rule='disability_20_of_40').required\nE + where StatusDecision(insured=True, qc_count_lower=19, qc_count_upper=19, required=19, window=(8068, 8069, 8070, 8071, 8072, ... 8089, 8090, 8091, 8092, 8093, 8094, 8095, 8096, 8097, 8098, 8099, 8100, 8101, 8102), upper_rule='disability_20_of_40') = InsuredStatus(version='track-b-insured-v1', month=datetime.date(2026, 12, 1), fully=StatusDecision(insured=True, qc_co...5: (8100, 8101, 8102), 2026: ()}), unknown_years=(), convention_years=mappingproxy({}), decided_despite_unknowns=False).disability\n\ntests/test_track_b_insured_status.py:754: AssertionError\n_________________ test_disability_twenty_qcs_boundary[20-True] _________________\n\ncount = 20, expected = True\n\n @pytest.mark.parametrize(\"count,expected\", [(19, False), (20, True)])\n def test_disability_twenty_qcs_boundary(count, expected):\n person = i.Person(date(1990, 2, 2))\n counts = {2021: 4, 2022: 4, 2023: 4, 2024: 4, 2025: count - 16}\n result = compute(person, date(2026, 12, 1), counts)\n assert result.fully.insured\n> assert result.disability.required == 20\nE AssertionError: assert 19 == 20\nE + where 19 = StatusDecision(insured=True, qc_count_lower=20, qc_count_upper=20, required=19, window=(8068, 8069, 8070, 8071, 8072, ... 8090, 8091, 8092, 8093, 8094, 8095, 8096, 8097, 8098, 8099, 8100, 8101, 8102, 8103), upper_rule='disability_20_of_40').required\nE + where StatusDecision(insured=True, qc_count_lower=20, qc_count_upper=20, required=19, window=(8068, 8069, 8070, 8071, 8072, ... 8090, 8091, 8092, 8093, 8094, 8095, 8096, 8097, 8098, 8099, 8100, 8101, 8102, 8103), upper_rule='disability_20_of_40') = InsuredStatus(version='track-b-insured-v1', month=datetime.date(2026, 12, 1), fully=StatusDecision(insured=True, qc_co...00, 8101, 8102, 8103), 2026: ()}), unknown_years=(), convention_years=mappingproxy({}), decided_despite_unknowns=False).disability\n\ntests/test_track_b_insured_status.py:754: AssertionError\n=========================== short test summary info ============================\nFAILED tests/test_track_b_insured_status.py::test_disability_twenty_qcs_boundary[19-False]\nFAILED tests/test_track_b_insured_status.py::test_disability_twenty_qcs_boundary[20-True]\n2 failed, 46 deselected in 44.47s\n", + "restored": true + }, + { + "name": "young_half_quarters_to_one_third", + "before": "max(6, len(elapsed) // 2)", + "after": "max(6, len(elapsed) // 3)", + "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status.py -k test_fred_brown_35_quarters_require_17_poms_140_example_1", + "exit_code": 1, + "seconds": 38.1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status.py::test_fred_brown_35_quarters_require_17_poms_140_example_1" + ], + "output": "F [100%]\n=================================== FAILURES ===================================\n__________ test_fred_brown_35_quarters_require_17_poms_140_example_1 ___________\n\n def test_fred_brown_35_quarters_require_17_poms_140_example_1():\n person = i.Person(date(1958, 5, 13), disability_onset=date(1988, 1, 15))\n result = compute(\n person,\n date(1988, 1, 1),\n {1980: 4, 1981: 4, 1982: 4, 1983: 4, 1984: 1},\n )\n> assert result.disability.required == 17\nE AssertionError: assert 11 == 17\nE + where 11 = StatusDecision(insured=True, qc_count_lower=17, qc_count_upper=17, required=11, window=(7918, 7919, 7920, 7921, 7922, ...922, 7923, 7924, 7925, 7926, 7927, 7928, 7929, 7930, 7931, 7932, 7933, 7934, 7935, 7936), upper_rule='under31_special').required\nE + where StatusDecision(insured=True, qc_count_lower=17, qc_count_upper=17, required=11, window=(7918, 7919, 7920, 7921, 7922, ...922, 7923, 7924, 7925, 7926, 7927, 7928, 7929, 7930, 7931, 7932, 7933, 7934, 7935, 7936), upper_rule='under31_special') = InsuredStatus(version='track-b-insured-v1', month=datetime.date(1988, 1, 1), fully=StatusDecision(insured=True, qc_cou...), 1986: (), 1987: (), 1988: ()}), unknown_years=(), convention_years=mappingproxy({}), decided_despite_unknowns=False).disability\n\ntests/test_track_b_insured_status.py:91: AssertionError\n=========================== short test summary info ============================\nFAILED tests/test_track_b_insured_status.py::test_fred_brown_35_quarters_require_17_poms_140_example_1\n1 failed, 47 deselected in 22.15s\n", + "restored": true + } + ], + "sha256_after": "b6bf989787bd465e080a435d77a178cee9ef861535eac190ab7fca9bd1033fc8", + "restored": true, + "verification": [ + { + "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status.py -x", + "result": "Initial suite:30passed234.26s; after DLI/world optimization and subsequent examples:42passed32.10s." + }, + { + "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status.py", + "result": "46passed34.70s before finaltwo registry tests; initial48-case run47passed1failed (FRAcompletionhad39ratherthan40QCs beforeFRAquarter; fixedinventedcompletionadds2009)." + }, + { + "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status.py -k \"dli_fra_cap or age_attainment\"", + "result": "2passed46deselected29.92s aftercorrectedcompletion." + }, + { + "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/estimates/test_birth_evidence_artifact.py -k \"not test_artifact_rebuild_reproduces\"", + "result": "13passed92.91s." + }, + { + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m black -l 79 --check tests/test_track_b_insured_status.py scripts/first_estimates_birth_evidence.py tests/estimates/test_birth_evidence_artifact.py", + "result": "3files would be left unchanged." + }, + { + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m ruff check tests/test_track_b_insured_status.py scripts/first_estimates_birth_evidence.py tests/estimates/test_birth_evidence_artifact.py", + "result": "Allchecks passed." + }, + { + "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_gross_benefits_fix_round_15_collections.py tests/test_track_b_gross_benefits_fix_round_15_arguments.py", + "result": "575 passed,36 failed in96.03s; all failures were missing insured_status COMPUTE/EVALUATE fixture map entries, fixed locally in arguments test." + }, + { + "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_gross_benefits_fix_round_15_arguments.py -k \"insured_status or CoverageYear or DisabilityPeriod or Person\"", + "result": "36 passed,272 deselected in11.03s." + }, + { + "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_gross_benefits_fix_round_15_collections.py tests/test_track_b_gross_benefits_fix_round_15_arguments.py", + "result": "611 passed in52.69s." + }, + { + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m black -l79 tests/test_track_b_gross_benefits_fix_round_15_arguments.py", + "result": "1 file unchanged." + }, + { + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m ruff check tests/test_track_b_gross_benefits_fix_round_15_arguments.py", + "result": "All checks passed." + } + ] + } +} diff --git a/tests/data/track_b/insured_status_sources/README.md b/tests/data/track_b/insured_status_sources/README.md new file mode 100644 index 000000000..81ff16163 --- /dev/null +++ b/tests/data/track_b/insured_status_sources/README.md @@ -0,0 +1,113 @@ +# Insured-status source captures + +Verification class: statutory conformance. These public statutory sources +support invented cases and published examples only. They admit no +population, behavioral or forecast claim. + +`manifest.json` pins all 44 staged captures with their URL, UTC retrieval +time, byte count, SHA-256 and capture format. POMS entries additionally +retain the exact transmittal and page date. The staging log was removed +only after all original byte counts and hashes were verified. The source +tests recompute every retained capture's hash and verify a specific rule +or documentary-purpose quote from every capture. The example registry at +`../insured_status_examples.yaml` checks every published figure against +its source and distinguishes computations, refusals, errata and unavailable +attachments. + +The three capture formats follow the gross-benefit manifest: + +- `http_body`: complete decoded HTTP response, unchanged. This includes + all 37 POMS sections, their table of contents and eCFR subpart B as of + 2026-10-07. +- `browser_text`: staged OACT quarter-of-coverage page text; `served_bodies` + records the original response identity. Its chart includes 2027. +- `http_text_excerpt`: relevant paragraphs of staged LII bodies, after + stripping tags, decoding entities, collapsing whitespace and + straightening apostrophes. Each entry retains the original complete + response's byte count and hash under `served_bodies`. Excerpts retain + 42 USC 413(a)-(d), 414(a)-(c), 416(i)(1)-(3) and (l), and 423(c)(1). + No replacement response was fetched. + +| Source | Use | +| --- | --- | +| RS 00301.000, .101 | Source inventory and insured-status overview | +| RS 00301.102 | Alien-worker SSPA requirement; eight cases and one alternative scenario, inventoried with the unsupported adjudicative surface | +| RS 00301.105-.107 | Fully insured and deemed nonprofit status; deemed status refusal | +| RS 00301.110 | Six QCs in a 13-quarter window | +| RS 00301.120, .122, .130-.132 | Disability 20/40, freeze preservation and exclusions, railroad/military refusal | +| RS 00301.140, .147-.150 | Young-worker special status, subsequent-period refusal, DLI, blindness and linked worksheet inventory | +| RS 00301.160-.161 | Medicare government-credit and premium-reduction refusal boundaries | +| RS 00301.200-.250 | Annual QCs, flexible assignment, exclusions, fiscal SE allocation and every 1978-2026 increment | +| RS 00301.301-.350 | Quarterly wages, agriculture, calendar/fiscal self-employment and maximum-earnings gift QCs; railroad and simplified-method boundaries | +| RS 00301.470, .475, .480, .600 | Deemed veterans, earned-basis wages, pre-1956 alternative test and vow-of-poverty refusals | +| RS 00301.800 | Exhibit shell and explicit record of missing linked images/PDF | +| 20 CFR 404 subpart B | Statutory rules, worked examples and the 404.115 cohort chart | +| 42 USC 413, 414, 416, 423 | Act 213, 214, 216(i)/(l), 223(c)(1) | +| SSA OACT QC page | Independent 1978-2027 chart and 2027 determination | + +The formula differential uses the already pinned R1 NAWI capture at +`../ret_sources/ssa_nawi_history.html` and its `manifest.json`, together +with `../ret_history.json`. Its decimal values are independently checked +against that capture. Exact rational arithmetic reproduces every QC +amount computable from the bundle, 1979-2026; no numerical tolerance is +needed. The 2027 determination uses the OACT capture's 2025 NAWI. POMS and +OACT agree on all 49 shared years, including POMS's joint 2010-2011 row. + +## Source limitations and findings + +RS 00301.800 contains links to two GIF images and one PDF, but their +response bodies were not staged. Its cohort chart cannot be reconstructed +from this capture, and no external source was fetched. CFR 404.115 does +contain a complete text cohort chart, which is used as an explicitly +identified alternative differential. RS 00301.149 likewise only points +to the SSA-1164 worksheet; no worksheet reproduction is claimed. + +RS 00301.340's short-year example states $10,900 of self-employment +income but allocates $3,600 to each of three quarters, totaling $10,800. +There are two readings. Taking the amount literally as already covered +SEI gives $10,900 / 3 per quarter. An unstated contribution-base ceiling +could explain the printed allocation if $10,900 instead means net +earnings before the ceiling: RS 00301.345 and Act 213(a)(2)(B)(iii) identify +$10,800 for a taxable year beginning in 1973, and $10,800 / 3 = $3,600. +The tests execute both readings. The capture does not state that ceiling +step, so this is an unresolved source assumption rather than a proven +arithmetic erratum. Both readings give three QCs; the allocated earnings +differ by $100 in total. The private allocation helper accepts already +covered SEI, and the public API continues to refuse short taxable years. + +RS 00301.345 prints the impossible taxable-year range “after 1975 and +before 1975” for its $14,100 SEI gift-QC bracket. Its ordinary wage table +unambiguously gives $14,100 for calendar year 1975. No fiscal-year +interpretation is inferred from that typo. + +RS 00301.102 example 4 states both May 12 and May 14, 2004 as the SSN +issuance date. Both are after the January 1, 2004 threshold. The registry +preserves both printed dates; alien-worker adjudication remains refused. +Examples 2, 5, 6 and 7 expressly say the worker never received an SSN. +The public declaration represents this with `ssn_never_assigned=True` and +returns the named alien-worker refusal, retained in the denominator. It +does not mistake this valid unsupported fact for a missing required date. + +RS 00301.120 distinguishes onset/freeze protection from the later DIB +waiting period. A person-month insured-status query does not itself +adjudicate an application, establish a freeze or determine cash entitlement. + +The registry separates helper arithmetic from public support: the fiscal +and short-tax-year allocation examples execute private allocation helpers, +while the public insured-status declaration refuses those special taxable +years until the caller supplies calendar-year credited earnings. + +Three disability examples have source-versus-rule differences pinned +beside the printed figures. RS 00301.140 example 6 excludes qualifying +endpoint quarters and prints 18 elapsed quarters/9 required QCs; retaining +those endpoints gives 20/10, still insured. Example 9 prints a denial +under a freeze, but disregarding the whole freeze as CFR 404.130(f) +requires when advantageous gives 20 QCs in 40 quarters and insurance. +RS 00301.147 example 3 prints 33 elapsed/16 required/8 available; flexible +assignment of the 1978 annual credit to the final disability quarter gives +34/17/9, still not insured. These differences need explicit review, and +are not counted as exact reproductions of the printed figures. + +RS 00301.147 example 2 says the person “requires and has 16” QCs. The +record contains 18; its statement that two additional QCs would meet 20/40 +confirms 18. The minimum requirement and insured conclusion reproduce. diff --git a/tests/data/track_b/insured_status_sources/ecfr_20cfr404_subpart_b.xml b/tests/data/track_b/insured_status_sources/ecfr_20cfr404_subpart_b.xml new file mode 100644 index 000000000..22683e2d6 --- /dev/null +++ b/tests/data/track_b/insured_status_sources/ecfr_20cfr404_subpart_b.xml @@ -0,0 +1,710 @@ + + +Subpart B—Insured Status and Quarters of Coverage + +Authority:Secs. 205(a), 212, 213, 214, 216, 217, 223, and 702(a)(5) of the Social Security Act (42 U.S.C. 405(a), 412, 413, 414, 416, 417, 423, and 902(a)(5)). + + +Source:45 FR 25384, Apr. 15, 1980, unless otherwise noted. + + +General + +§ 404.101 Introduction. +

(a) Insured status. This subpart explains what we mean when we say that a person has insured status under the social security program. It also describes how a person may become fully insured, currently insured or insured for disability benefits. Your insured status is a basic factor in determining if you are entitled to old-age or disability insurance benefits or to a period of disability. It is also a basic factor in determining if dependents' or survivors' insurance benefits or a lump-sum death payment are payable based on your earnings record. If you are neither fully nor currently insured, no benefits are payable based on your earnings. (Subpart D of this part describes these benefits and the kind of insured status required for each.) In §§ 404.110 through 404.120 we tell how we determine if you are fully or currently insured. The rules for determining if you are insured for purposes of establishing a period of disability or becoming entitled to disability insurance benefits are in §§ 404.130 through 404.133. Whether you have the required insured status depends on the number of quarters of coverage (QCs) you have acquired.

+

(b) QCs. This subpart also sets out our rules on crediting you with QCs. QCs are used in determining insured status. In general, you are credited with QCs based on the wages you are paid and the self-employment income you derive during certain periods. (See subpart K of this part for a definition of wages and self-employment income.) Our rules on how and when you acquire a QC are contained in §§ 404.140 through 404.146.

+
+ + +§ 404.102 Definitions. +

For the purpose of this subpart—

+

Act means the Social Security Act, as amended.

+

Age means how many years old you are. You reach a particular age on the day before your birthday. For example, if your sixty-second birthday is on July 1, 1979, you became age 62 on June 30, 1979.

+

Quarter or calendar quarter means a period of three calendar months ending March 31, June 30, September 30, or December 31 of any year.

+

We, our, or us means the Social Security Administration.

+

You or your means the worker whose insured status is being considered.

+
+ +
+ +Fully Insured Status + +§ 404.110 How we determine fully insured status. +

(a) General. We describe how we determine the number of quarters of coverage (QCs) you need to be fully insured in paragraphs (b), (c), and (d) of this section. The table in § 404.115 may be used to determine the number of QCs you need to be fully insured under paragraph (b) of this section. We consider certain World War II veterans to have died fully insured (see § 404.111). We also consider certain employees of private nonprofit organizations to be fully insured if they meet special requirements (see § 404.112).

+

(b) How many QCs you need to be fully insured. (1) You need at least 6 QCs but not more than 40 QCs to be fully insured. A person who died before 1951 with at least 6 QCs is fully insured.

+

(2) You are fully insured for old-age insurance benefits if you have one QC (whenever acquired) for each calendar year elapsing after 1950 or, if later, after the year in which you became age 21, and before the year you reach retirement age, that is, before—

+

(i) The year you become age 62, if you are a woman;

+

(ii) The year you become age 62, if you are a man who becomes age 62 after 1974;

+

(iii) The year 1975, if you are a man who became age 62 in 1973 or 1974; or

+

(iv) The year you became age 65, if you are a man who became age 62 before 1973.

+

(3) A person who is otherwise eligible for survivor's benefits and who files an application will be entitled to benefits based on your earnings if you die fully insured. You will be fully insured if you had one QC (whenever acquired) for each calendar year elapsing after 1950 or, if later, after the year you became age 21, and before the earlier of the following years:

+

(i) The year you die; or

+

(ii) The year you reach retirement age as shown in paragraph (b)(2) of this section.

+

(c) How a period of disability affects the number of QCs you need. In determining the number of elapsed years under paragraph (b) of this section, we do not count as an elapsed year any year which is wholly or partly in a period of disability we established for you. For example, if we established a period of disability for you from December 5, 1975 through January 31, 1977, the three years, 1975, 1976 and 1977, would not be counted as elapsed years.

+

(d) How we credit QCs for fully insured status based on your total wages before 1951—(1) General. For purposes of paragraph (b) of this section, we may use the following rules in crediting QCs based on your wages before 1951 instead of the rule in § 404.141(b)(1).

+

(i) We may consider you to have one QC for each $400 of your total wages before 1951, as defined in paragraph (d)(2) of this section, if you have at least 7 elapsed years as determined under paragraph (b)(2) or (b)(3) of this section; and the number of QCs determined under this paragraph plus the number of QCs credited to you for periods after 1950 make you fully insured.

+

(ii) If you file an application in June 1992 or later and you are not entitled to a benefit under section 227 of the Act in the month the application is made, we may consider you to have at least one QC before 1951 if you have $400 or more total wages before 1951, as defined in paragraph (d)(2) of this section, provided that the number of QCs credited to you under this paragraph plus the number of QCs credited to you for periods after 1950 make you fully insured.

+

(2) What are total wages before 1951. For purposes of paragraph (d)(1) of this section, your total wages before 1951 include—

+

(i) Remuneration credited to you before 1951 on the records of the Secretary;

+

(ii) Wages considered paid to you before 1951 under section 217 of the Act (relating to benefits in case of veterans);

+

(iii) Compensation under the Railroad Retirement Act of 1937 before 1951 that can be credited to you under title II of the Social Security Act; and

+

(iv) Wages considered paid to you before 1951 under section 231 of the Act (relating to benefits in case of certain persons interned in the United States during World War II).

+

(e) When your fully insured status begins. You are fully insured as of the first day of the calendar quarter in which you acquire the last needed QC (see § 404.145).

+[45 FR 25384, Apr. 15, 1980, as amended at 50 FR 36573, Sept. 9, 1985; 57 FR 23156, June 2, 1992; 83 FR 21708, May 10, 2018] + +
+ + +§ 404.111 When we consider a person fully insured based on World War II active military or naval service. +

We consider that a person, who was not otherwise fully insured, died fully insured if—

+

(a) The person was in the active military or naval service of the United States during World War II;

+

(b) The person died within three years after separation from service and before July 27, 1954; and

+

(c) The conditions in § 404.1350 that permit us to consider the person fully insured are met.

+

(d) The provisions of this section do not apply to persons filing applications after May 31, 1992, unless a survivor is entitled to benefits under section 202 of the Act based on the primary insurance amount of the fully insured person for the month preceding the month in which the application is made.

+[45 FR 25384, Apr. 15, 1980, as amended at 57 FR 23157, June 2, 1992] + +
+ + +§ 404.112 When we consider certain employees of private nonprofit organizations to be fully insured. +

If you are age 55 or over on January 1, 1984, and are on that date an employee of an organization described in § 404.1025(a) which does not have in effect a waiver certificate under section 3121(k) of the Code on that date and whose employees are mandatorily covered as a result of section 102 of Pub. L. 98-21, we consider you to be fully insured if you meet the following requirements:

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Your age on January 1, 1984 is—QC's acquired after Dec. 31, 1983
60 or over6
59 or over but less than age 608
58 or over but less than age 5912
57 or over but less than age 5816
55 or over but less than age 5720
+
+[50 FR 36573, Sept. 9, 1985] + +
+ + +§ 404.115 Table for determining the quarters of coverage you need to be fully insured. +

(a) General. You may use the following table to determine the number of quarters of coverage (QCs) you need to be fully insured under § 404.110. Paragraphs (b) and (c) of this section tell you how to use this table.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Worker who reaches retirement age as described in § 404.110(b)(2)Worker who dies before reaching retirement age as described in § 404.110(b)(2)
Col. I—Date of birthCol. II 1Col. III 2—Year of deathCol. IV 3Col. V 4—Age in year of death
MenWomen
Jan. 1, 1893 or earlier665 195766 28
Jan. 2, 1893 to Jan. 1, 1894761958729
Jan. 2, 1894 to Jan. 1, 1895861959830
Jan. 2, 1895 to Jan. 1, 1896961960931
Jan. 2, 1896 to Jan. 1, 189710719611032
Jan. 2, 1897 to Jan. 1, 189811819621133
Jan. 2, 1898 to Jan. 1, 189912919631234
Jan. 2, 1899 to Jan. 1, 1900131019641335
Jan. 2, 1900 to Jan. 1, 1901141119651436
Jan. 2, 1901 to Jan. 1, 1902151219661537
Jan. 2, 1902 to Jan. 1, 1903161319671638
Jan. 2, 1903 to Jan. 1, 1904171419681739
Jan. 2, 1904 to Jan. 1, 1905181519691840
Jan. 2, 1905 to Jan. 1, 1906191619701941
Jan. 2, 1906 to Jan. 1, 1907201719712042
Jan. 2, 1907 to Jan. 1, 1908211819722143
Jan. 2, 1908 to Jan. 1, 1909221919732244
Jan. 2, 1909 to Jan. 1, 1910232019742345
Jan. 2, 1910 to Jan. 1, 1911242119752446
Jan. 2, 1911 to Jan. 1, 1912242219762547
Jan. 2, 1912 to Jan. 1, 1913242319772648
Jan. 2, 1913 to Jan. 1, 1914242419782749
Jan. 2, 1914 to Jan. 1, 1915252519792850
Jan. 2, 1915 to Jan. 1, 1916262619802951
Jan. 2, 1916 to Jan. 1, 1917272719813052
Jan. 2, 1917 to Jan. 1, 1918282819823153
Jan. 2, 1918 to Jan. 1, 1919292919833254
Jan. 2, 1919 to Jan. 1, 1920303019843355
Jan. 2, 1920 to Jan. 1, 1921313119853456
Jan. 2, 1921 to Jan. 1, 1922323219863557
Jan. 2, 1922 to Jan. 1, 1923333319873658
Jan. 2, 1923 to Jan. 1, 1924343419883759
Jan. 2, 1924 to Jan. 1, 1925353519893860
Jan. 2, 1925 to Jan. 1, 1926363619903961
Jan. 2, 1926 to Jan. 1, 192737377 19914062
Jan. 2, 1927 to Jan. 1, 19283838 + + +
Jan. 2, 1928 to Jan. 1, 19293939 + + +
Jan. 2, 1929 or later40 + + + +
1 Number of QCs required for fully insured status; living worker or worker who dies after reaching retirement age. +
2 Worker born before Jan. 2, 1930 who dies before reaching retirement age. +
3 Number of QCs required for fully insured status. +
4 Worker born Jan. 2, 1930 or later, who dies before reaching retirement age. +
5 Or earlier. +
6 Or younger. +
7 Or later.
+
+

(b) Number of QCs you need. The QCs you need for fully insured status are in column II opposite your date of birth in column I. If a worker dies before reaching retirement age as described in § 404.110(b)(2), the QCs needed for fully insured status are shown in column IV opposite—

+

(1) The year of death in column III, if the worker was born before January 2, 1930; or

+

(2) The age in the year of death in column V, if the worker was born after January 1, 1930.

+

(c) How a period of disability affects the number of QCs you need. If you had a period of disability established for you, it affects the number of QCs you need to be fully insured (see § 404.110(c)). For each year which is wholly or partly in a period of disability, subtract one QC from the number of QCs shown in the appropriate line and column of the table as explained in paragraph (b) of this section.

+
+ +
+ +Currently Insured Status + +§ 404.120 How we determine currently insured status. +

(a) What the period is for determining currently insured status. You are currently insured if you have at least 6 quarters of coverage (QCs) during the 13-quarter period ending with the quarter in which you—

+

(1) Die;

+

(2) Most recently became entitled to disability insurance benefits; or

+

(3) Became entitled to old-age insurance benefits.

+

(b) What quarters are not counted as part of the 13-quarter period. We do not count as part of the 13-quarter period any quarter all or part of which is included in a period of disability established for you, except that the first and last quarters of the period of disability may be counted if they are QCs (see § 404.146(d)).

+
+ +
+ +Disability Insured Status + +§ 404.130 How we determine disability insured status. +

(a) General. We have four different rules for determining if you are insured for purposes of establishing a period of disability or becoming entitled to disability insurance benefits. To have disability insured status, you must meet one of these rules and you must be fully insured (see § 404.132 which tells when the period ends for determining the number of quarters of coverage (QCs) you need to be fully insured).

+

(b) Rule I—You must meet the 20/40 requirement. You are insured in a quarter for purposes of establishing a period of disability or becoming entitled to disability insurance benefits if in that quarter—

+

(1) You are fully insured; and

+

(2) You have at least 20 QCs in the 40-quarter period (see paragraph (f) of this section) ending with that quarter.

+

(c) Rule II—You become disabled before age 31. You are insured in a quarter for purposes of establishing a period of disability or becoming entitled to disability insurance benefits if in that quarter—

+

(1) You have not become (or would not become) age 31;

+

(2) You are fully insured; and

+

(3) You have QCs in at least one-half of the quarters during the period ending with that quarter and beginning with the quarter after the quarter you became age 21; however—

+

(i) If the number of quarters during this period is an odd number, we reduce the number by one; and

+

(ii) If the period has less than 12 quarters, you must have at least 6 QCs in the 12-quarter period ending with that quarter.

+

(d) Rule III—You had a period of disability before age 31. You are insured in a quarter for purposes of establishing a period of disability or becoming entitled to disability insurance benefits if in that quarter—

+

(1) You are disabled again at age 31 or later after having had a prior period of disability established which began before age 31 and for which you were only insured under paragraph (c) of this section; and

+

(2) You are fully insured and have QCs in at least one-half the calendar quarters in the period beginning with the quarter after the quarter you became age 21 and through the quarter in which the later period of disability begins, up to a maximum of 20 QCs out of 40 calendar quarters; however—

+

(i) If the number of quarters during this period is an odd number, we reduce the number by one;

+

(ii) If the period has less than 12 quarters, you must have at least 6 QCs in the 12-quarter period ending with that quarter; and

+

(iii) No monthly benefits may be paid or increased under Rule III before May 1983.

+

(e) Rule IV—You are statutorily blind. You are insured in a quarter for purposes of establishing a period of disability or becoming entitled to disability insurance benefits if in that quarter—

+

(1) You are disabled by blindness as defined in § 404.1581; and

+

(2) You are fully insured.

+

(f) How we determine the 40-quarter or other period. In determining the 40-quarter period or other period in paragraph (b), (c), or (d) of this section, we do not count any quarter all or part of which is in a prior period of disability established for you, unless the quarter is the first or last quarter of this period and the quarter is a QC. However, we will count all the quarters in the prior period of disability established for you if by doing so you would be entitled to benefits or the amount of the benefit would be larger.

+[49 FR 28547, July 13, 1984, as amended at 55 FR 7313, Mar. 1, 1990] + +
+ + +§ 404.131 When you must have disability insured status. +

(a) For a period of disability. To establish a period of disability, you must have disability insured status in the quarter in which you become disabled or in a later quarter in which you are disabled.

+

(b) For disability insurance benefits. (1) To become entitled to disability insurance benefits, you must have disability insured status in the first full month that you are disabled as described in § 404.1501(a), or if later—

+

(i) The 17th month (if you have to serve a waiting period described in § 404.315(d)) before the month in which you file an application for disability insurance benefits; or

+

(ii) The 12th month (if you do not have to serve a waiting period) before the month in which you file an application for disability insurance benefits.

+

(2) If you do not have disability insured status in a month specified in paragraph (b)(1) of this section, you will be insured for disability insurance benefits beginning with the first month after that month in which you do meet the insured status requirement and you also meet all other requirements for disability insurance benefits described in § 404.315.

+
+ + +§ 404.132 How we determine fully insured status for a period of disability or disability insurance benefits. +

In determining if you are fully insured for purposes of paragraph (b), (c), (d), or (e) of § 404.130 on disability insured status, we use the fully insured status requirements in § 404.110, but apply the following rules in determining when the period of elapsed years ends:

+

(a) If you are a woman, or a man born after January 1, 1913, the period of elapsed years in § 404.110(b) used in determining the number of quarters of coverage (QCs) you need to be fully insured ends as of the earlier of—

+

(1) The year you become age 62; or

+

(2) The year in which—

+

(i) Your period of disability begins;

+

(ii) Your waiting period begins (see § 404.315(d)); or

+

(iii) You become entitled to disability insurance benefits (if you do not have to serve a waiting period).

+

(b) If you are a man born before January 2, 1913, the period of elapsed years in § 404.110(b) used in determining the number of QCs you need to be fully insured ends as of the earlier of—

+

(1) The year 1975; or

+

(2) The year specified in paragraph (a)(2) of this section.

+[45 FR 25384, Apr. 15, 1980, as amended at 49 FR 28547, July 13, 1984] + +
+ + +§ 404.133 When we give you quarters of coverage based on military service to establish a period of disability. +

For purposes of establishing a period of disability only, we give you quarters of coverage (QCs) for your military service before 1957 (see subpart N of this part). We do this even though we may not use that military service for other purposes of title II of the Act because a periodic benefit is payable from another Federal agency based in whole or in part on the same period of military service.

+
+ +
+ +Quarters of Coverage + +§ 404.140 What is a quarter of coverage. +

(a) General. A quarter of coverage (QC) is the basic unit of social security coverage used in determining a worker's insured status. We credit you with QCs based on your earnings covered under social security.

+

(b) How we credit QCs based on earnings before 1978 (General). Before 1978, wages were generally reported on a quarterly basis and self-employment income was reported on an annual basis. For the most part, we credit QCs for calendar years before 1978 based on your quarterly earnings. For these years, as explained in § 404.141, we generally credit you with a QC for each calendar quarter in which you were paid at least $50 in wages or were credited with at least $100 of self-employment income. Section 404.142 tells how self-employment income derived in a taxable year beginning before 1978 is credited to specific calendar quarters for purposes of § 404.141.

+

(c) How we credit QCs based on earnings after 1977 (General). After 1977, both wages and self-employment income are generally reported on an annual basis. For calendar years after 1977, as explained in § 404.143, we generally credit you with a QC for each part of your total covered earnings in a calendar year that equals the amount required for a QC in that year. Section 404.143 also tells how the amount required for a QC will be increased in the future as average wages increase. Section 404.144 tells how self-employment income derived in a taxable year beginning after 1977 is credited to specific calendar years for purposes of § 404.143.

+

(d) When a QC is acquired and when a calendar quarter is not a QC (general). Section 404.145 tells when a QC is acquired and § 404.146 tells when a calendar quarter cannot be a QC. These rules apply when we credit QCs under § 404.141 or § 404.143.

+
+ + +§ 404.141 How we credit quarters of coverage for calendar years before 1978. +

(a) General. The rules in this section tell how we credit calendar quarters as quarters of coverage (QCs) for calendar years before 1978. We credit you with a QC for a calendar quarter based on the amount of wages you were paid and self-employment income you derived during certain periods. The rules in paragraphs (b), (c), and (d) of this section are subject to the limitations in § 404.146, which tells when a calendar quarter cannot be a QC.

+

(b) How we credit QCs based on wages paid in, or self-employment income credited to, a calendar quarter. We credit you with a QC for a calendar quarter in which—

+

(1) You were paid wages of $50 or more (see paragraph (c) of this section for an exception relating to wages paid for agricultural labor); or

+

(2) You were credited (under § 404.142) with self-employment income of $100 or more.

+

(c) How we credit QCs based on wages paid for agricultural labor in a calendar year after 1954. (1) We credit QCs based on wages for agricultural labor depending on the amount of wages paid during a calendar year for that work. If you were paid wages for agricultural labor in a calendar year after 1954 and before 1978, we credit you with QCs for calendar quarters in that year which are not otherwise QCs according to the following table.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
If the wages paid to you in a calendar year for agricultural labor wereWe credit you withAnd assign: 1
$400 or more4 QCsAll.
At least $300 but less than $4003 QCsLast 3.
At least $200 but less than $3002 QCsLast 2.
At least $100 but less than $2001 QCLast.
Less than $100No QCs + +
1 One QC to each of the following calendar quarters in that year.
+
+

(2) When we assign QCs to calendar quarters in a year as shown in the table in paragraph (c)(1) of this section, you might not meet (or might not meet as early in the year as otherwise possible) the requirements to be fully or currently insured, to be entitled to a computation or recomputation of your primary insurance amount, or to establish a period of disability. If this happens, we assign the QCs to different quarters in that year than those shown in the table if this assignment permits you to meet these requirements (or meet them earlier in the year). We can only reassign QCs for purposes of meeting these requirements.

+

(d) How we credit QCs based on wages paid or self-employment income derived in a year. (1) If you were paid wages in a calendar year after 1950 and before 1978 at least equal to the annual wage limitation in effect for that year as described in §§ 404.1047 and 404.1096, we credit you with a QC for each quarter in that calendar year. If you were paid at least $3,000 wages in a calendar year before 1951, we credit you with a QC for each quarter in that calendar year.

+

(2) If you derived self-employment income (or derived self-employment income and also were paid wages) during a taxable year beginning after 1950 and before 1978 at least equal to the self-employment income and wage limitation in effect for that year as described in § 404.1068(b), we credit you with a QC for each calendar quarter wholly or partly in that taxable year.

+[45 FR 25384, Apr. 15, 1980; 45 FR 41931, June 23, 1980, as amended at 70 FR 14977, Mar. 24, 2005] + +
+ + +§ 404.142 How we credit self-employment income to calendar quarters for taxable years beginning before 1978. +

In crediting quarters of coverage under § 404.141(b)(2), we credit any self-employment income you derived during a taxable year that began before 1978 to calendar quarters as follows:

+

(a) If your taxable year was a calendar year, we credit your self-employment income equally to each quarter of that calendar year.

+

(b) If your taxable year was not a calendar year (that is, it began on a date other than January 1, or was less than a calendar year), we credit your self-employment income equally—

+

(1) To the calendar quarter in which your taxable year ended; and

+

(2) To each of the next three or fewer preceding quarters that were wholly or partly in your taxable year.

+
+ + +§ 404.143 How we credit quarters of coverage for calendar years after 1977. +

(a) Crediting quarters of coverage (QCs). For calendar years after 1977, we credit you with a QC for each part of the total wages paid and self-employment income credited (under § 404.144) to you in a calendar year that equals the amount required for a QC in that year. For example, if the total of your wages and self-employment income for a calendar year is more than twice, but less than 3 times, the amount required for a QC in that year, we credit you with only 2 QCs for the year. The rules for crediting QCs in this section are subject to the limitations in § 404.146, which tells when a calendar quarter cannot be a QC. In addition, we cannot credit you with more than four QCs for any calendar year. The amount of wages and self-employment income that you must have for each QC is—

+

(1) $250 for calendar year 1978; and

+

(2) For each calendar year after 1978, an amount determined by the Commissioner for that year (on the basis of a formula in section 213(d)(2) of the Act which reflects national increases in average wages). The amount determined by the Commissioner is published in the Federal Register on or before November 1 of the preceding year and included in the appendix to this subpart.

+

(b) Assigning QCs. We assign a QC credited under paragraph (a) of this section to a specific calendar quarter in the calendar year only if the assignment is necessary to—

+

(1) Give you fully or currently insured status;

+

(2) Entitle you to a computation or recomputation of your primary insurance amount; or

+

(3) Permit you to establish a period of disability.

+[45 FR 25834, Apr. 15, 1980, as amended at 62 FR 38450, July 18, 1997] + +
+ + +§ 404.144 How we credit self-employment income to calendar years for taxable years beginning after 1977. +

In crediting quarters of coverage under § 404.143(a), we credit self-employment income you derived during a taxable year that begins after 1977 to calendar years as follows:

+

(a) If your taxable year is a calendar year or begins and ends within the same calendar year, we credit your self-employment income to that calendar year.

+

(b) If your taxable year begins in one calendar year and ends in the following calendar year, we allocate proportionately your self-employment income to the two calendar years on the basis of the number of months in each calendar year which are included completely within your taxable year. We consider the calendar month in which your taxable year ends as included completely within your taxable year.

+ +Example:For the taxable year beginning May 15, 1978, and ending May 14, 1979, your self-employment income is $1200. We credit +7/12 ($700) of your self-employment income to calendar year 1978 and +5/12 ($500) of your self-employment income to calendar year 1979. +
+ + +§ 404.145 When you acquire a quarter of coverage. +

If we credit you with a quarter of coverage (QC) for a calendar quarter under paragraph (b), (c), or (d) of § 404.141 for calendar years before 1978 or assign it to a specific calendar quarter under paragraph (b) of § 404.143 for calendar years after 1977, you acquire the QC as of the first day of the calendar quarter.

+
+ + +§ 404.146 When a calendar quarter cannot be a quarter of coverage. +

This section applies when we credit you with quarters of coverage (QCs) under § 404.141 for calendar years before 1978 and under § 404.143 for calendar years after 1977. We cannot credit you with a QC for—

+

(a) A calendar quarter that has not begun;

+

(b) A calendar quarter that begins after the quarter of your death;

+

(c) A calendar quarter that has already been counted as a QC; or

+

(d) A calendar quarter that is included in a period of disability established for you, unless—

+

(1) The quarter is the first or the last quarter of this period; or

+

(2) The period of disability is not taken into consideration (see § 404.320(a)).

+
+ + +Appendix to Subpart B of Part 404—Quarter of Coverage Amounts for Calendar Years After 1978 + +

This appendix shows the amount determined by the Commissioner that is needed for a quarter of coverage for each year after 1978 as explained in § 404.143. We publish the amount as a Notice in the Federal Register on or before November 1 of the preceding year. The amounts determined by the Commissioner are as follows:

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Calendar yearAmount needed
1979$260
1980290
1981310
1982340
1983370
1984390
1985410
1986440
1987460
1988470
1989500
1990520
1991540
1992570
+
+[45 FR 25384, Apr. 15, 1980, as amended at 52 FR 8247, Mar. 17, 1987; 57 FR 44096, Sept. 24, 1992; 62 FR 38450, July 18, 1997] + +
+ +
+
diff --git a/tests/data/track_b/insured_status_sources/lii_usc_42_413_excerpts.txt b/tests/data/track_b/insured_status_sources/lii_usc_42_413_excerpts.txt new file mode 100644 index 000000000..3128e88bb --- /dev/null +++ b/tests/data/track_b/insured_status_sources/lii_usc_42_413_excerpts.txt @@ -0,0 +1,7 @@ +(a) Definitions For the purposes of this subchapter— (1) The term “quarter”, and the term “ calendar quarter ”, mean a period of three calendar months ending on March 31, June 30, September 30, or December 31. (2) (A) The term “ quarter of coverage ” means— (i) for calendar years before 1978, and subject to the provisions of subparagraph (B), a quarter in which an individual has been paid $50 or more in wages (except wages for agricultural labor paid after 1954) or for which he has been credited (as determined under section 412 of this title ) with $100 or more of self-employment income; and (ii) for calendar years after 1977, and subject to the provisions of subparagraph (B), each portion of the total of the wages paid and the self-employment income credited (pursuant to section 412 of this title ) to an individual in a calendar year which equals the amount required for a quarter of coverage in that calendar year (as determined under subsection (d)), with such quarter of coverage being assigned to a specific calendar quarter in such calendar year only if necessary in the case of any individual who has attained age 62 or died or is under a disability and the requirements for insured status in subsection (a) or (b) of section 414 of this title , the requirements for entitlement to a computation or recomputation of his primary insurance amount, or the requirements of paragraph (3) of section 416(i) of this title would not otherwise be met. (B) Notwithstanding the provisions of subparagraph (A)— (i) no quarter after the quarter in which an individual dies shall be a quarter of coverage , and no quarter any part of which is included in a period of disability (other than the initial quarter and the last quarter of such period) shall be a quarter of coverage ; (ii) if the wages paid to an individual in any calendar year equal $3,000 in the case of a calendar year before 1951, or $3,600 in the case of a calendar year after 1950 and before 1955, or $4,200 in the case of a calendar year after 1954 and before 1959, or $4,800 in the case of a calendar year after 1958 and before 1966, or $6,600 in the case of a calendar year after 1965 and before 1968, or $7,800 in the case of a calendar year after 1967 and before 1972, or $9,000 in the case of the calendar year 1972, or $10,800 in the case of the calendar year 1973, or $13,200 in the case of the calendar year 1974, or an amount equal to the contribution and benefit base (as determined under section 430 of this title ) in the case of any calendar year after 1974 and before 1978 with respect to which such contribution and benefit base is effective, each quarter of such year shall (subject to clauses (i) and (v)) be a quarter of coverage; (iii) if an individual has self-employment income for a taxable year, and if the sum of such income and the wages paid to him during such year equals $3,600 in the case of a taxable year beginning after 1950 and ending before 1955, or $4,200 in the case of a taxable year ending after 1954 and before 1959, or $4,800 in the case of a taxable year ending after 1958 and before 1966, or $6,600 in the case of a taxable year ending after 1965 and before 1968, or $7,800 in the case of a taxable year ending after 1967 and before 1972, or $9,000 in the case of a taxable year beginning after 1971 and before 1973, or $10,800 in the case of a taxable year beginning after 1972 and before 1974, or $13,200 in the case of a taxable year beginning after 1973 and before 1975, or an amount equal to the contribution and benefit base (as determined under section 430 of this title ) which is effective for the calendar year in the case of any taxable year beginning in any calendar year after 1974 and before 1978, each quarter any part of which falls in such year shall (subject to clauses (i) and (v)) be a quarter of coverage; (iv) if an individual is paid wages for agricultural labor in a calendar year after 1954 and before 1978, then, subject to clauses (i) and (v), (I) the last quarter of such year which can be but is not otherwise a quarter of coverage shall be a quarter of coverage if such wages equal or exceed $100 but are less than $200; (II) the last two quarters of such year which can be but are not otherwise quarters of coverage shall be quarters of coverage if such wages equal or exceed $200 but are less than $300; (III) the last three quarters of such year which can be but are not otherwise quarters of coverage shall be quarters of coverage if such wages equal or exceed $300 but are less than $400; and (IV) each quarter of such year which is not otherwise a quarter of coverage shall be a quarter of coverage if such wages are $400 or more; (v) no quarter shall be counted as a quarter of coverage prior to the beginning of such quarter; (vi) not more than one quarter of coverage may be credited to a calendar quarter; and (vii) no more than four quarters of coverage may be credited to any calendar year after 1977. If in the case of an individual who has attained age 62 or died or is under a disability and who has been paid wages for agricultural labor in a calendar year after 1954 and before 1978, the requirements for insured status in subsection (a) or (b) of section 414 of this title , the requirements for entitlement to a computation or recomputation of his primary insurance amount, or the requirements of paragraph (3) of section 416(i) of this title are not met after assignment of quarters of coverage to quarters in such year as provided in clause (iv) of the preceding sentence, but would be met if such quarters of coverage were assigned to different quarters in such year, then such quarters of coverage shall instead be assigned, for purposes only of determining compliance with such requirements, to such different quarters. If, in the case of an individual who did not die prior to January 1, 1955 , and who attained age 62 (if a woman) or age 65 (if a man) or died before July 1, 1957 , the requirements for insured status in section 414(a)(3) of this title are not met because of his having too few quarters of coverage but would be met if his quarters of coverage in the first calendar year in which he had any covered employment had been determined on the basis of the period during which wages were earned rather than on the basis of the period during which wages were paid (any such wages paid that are reallocated on an earned basis shall not be used in determining quarters of coverage for subsequent calendar years), then upon application filed by the individual or his survivors and satisfactory proof of his record of wages earned being furnished by such individual or his survivors, the quarters of coverage in such calendar year may be determined on the basis of the periods during which wages were earned. + +(b) Crediting of wages paid in 1937 With respect to wages paid to an individual in the six-month periods commencing either January 1, 1937 , or July 1, 1937 ; (A) if wages of not less than $100 were paid in any such period, one-half of the total amount thereof shall be deemed to have been paid in each of the calendar quarters in such period; and (B) if wages of less than $100 were paid in any such period, the total amount thereof shall be deemed to have been paid in the latter quarter of such period, except that if in any such period, the individual attained age sixty-five, all of the wages paid in such period shall be deemed to have been paid before such age was attained. + +(c) Alternative method for determining quarters of coverage with respect to wages in period from 1937 to 1950 For purposes of sections 414(a) and 415(d) of this title, an individual shall be deemed to have one quarter of coverage for each $400 of his total wages prior to 1951 (as defined in section 415(d)(1)(C) of this title ), except where such individual is not a fully insured individual on the basis of the number of quarters of coverage so derived plus the number of quarters of coverage derived from the wages and self-employment income credited to such individual for periods after 1950. + +(d) Amount required for a quarter of coverage (1) The amount of wages and self-employment income which an individual must have in order to be credited with a quarter of coverage in any year under subsection (a)(2)(A)(ii) shall be $250 in the calendar year 1978 and the amount determined under paragraph (2) of this subsection for years after 1978. (2) The Commissioner of Social Security shall, on or before November 1 of 1978 and of every year thereafter, determine and publish in the Federal Register the amount of wages and self-employment income which an individual must have in order to be credited with a quarter of coverage in the succeeding calendar year. The amount required for a quarter of coverage shall be the larger of— (A) the amount in effect in the calendar year in which the determination under this subsection is made, or (B) the product of the amount prescribed in paragraph (1) which is required for a quarter of coverage in 1978 and the ratio of the national average wage index (as defined in section 409(k)(1) of this title ) for the calendar year before the year in which the determination under this paragraph is made to the national average wage index (as so defined) for 1976, with such product, if not a multiple of $10, being rounded to the next higher multiple of $10 where such amount is a multiple of $5 but not of $10 and to the nearest multiple of $10 in any other case. diff --git a/tests/data/track_b/insured_status_sources/lii_usc_42_414_excerpts.txt b/tests/data/track_b/insured_status_sources/lii_usc_42_414_excerpts.txt new file mode 100644 index 000000000..f191e6054 --- /dev/null +++ b/tests/data/track_b/insured_status_sources/lii_usc_42_414_excerpts.txt @@ -0,0 +1,5 @@ +(a) “Fully insured individual” defined The term “ fully insured individual ” means any individual who had not less than— (1) one quarter of coverage (whenever acquired) for each calendar year elapsing after 1950 (or, if later, the year in which he attained age 21) and before the year in which he died or (if earlier) the year in which he attained age 62, except that in no case shall an individual be a fully insured individual unless he has at least 6 quarters of coverage; or (2) 40 quarters of coverage; or (3) in the case of an individual who died before 1951, 6 quarters of coverage; not counting as an elapsed year for purposes of paragraph (1) any year any part of which was included in a period of disability (as defined in section 416(i) of this title ), and who satisfies the criterion specified in subsection (c). + +(b) “Currently insured individual” defined The term “ currently insured individual ” means any individual who had not less than six quarters of coverage during the thirteen-quarter period ending with (1) the quarter in which he died, (2) the quarter in which he became entitled to old-age insurance benefits, (3) the quarter in which he became entitled to primary insurance benefits under this subchapter as in effect prior to August 28, 1950 , or (4) in the case of any individual entitled to disability insurance benefits, the quarter in which he most recently became entitled to disability insurance benefits, not counting as part of such thirteen-quarter period any quarter any part of which was included in a period of disability unless such quarter was a quarter of coverage, and who satisfies the criterion specified in subsection (c). + +(c) Criterion described For purposes of subsections (a) and (b), the criterion specified in this subsection is that the individual, if not a United States citizen or national— (1) has been assigned a social security account number that was, at the time of assignment, or at any later time, consistent with the requirements of subclause (I) or (III) of section 405(c)(2)(B)(i) of this title ; or (2) at the time any such quarters of coverage are earned— (A) is described in subparagraph (B) or (D) of section 1101(a)(15) of title 8 , (B) is lawfully admitted temporarily to the United States for business (in the case of an individual described in such subparagraph (B)) or the performance as a crewman (in the case of an individual described in such subparagraph (D)), and (C) the business engaged in or service as a crewman performed is within the scope of the terms of such individual's admission to the United States . diff --git a/tests/data/track_b/insured_status_sources/lii_usc_42_416_excerpts.txt b/tests/data/track_b/insured_status_sources/lii_usc_42_416_excerpts.txt new file mode 100644 index 000000000..af2036a22 --- /dev/null +++ b/tests/data/track_b/insured_status_sources/lii_usc_42_416_excerpts.txt @@ -0,0 +1,7 @@ +(i) (1) Except for purposes of sections 402(d) , 402(e) , 402(f) , 423 , and 425 of this title, the term “disability” means (A) inability to engage in any substantial gainful activity by reason of any medically determinable physical or mental impairment which can be expected to result in death or has lasted or can be expected to last for a continuous period of not less than 12 months, or (B) blindness; and the term “blindness” means central visual acuity of 20/200 or less in the better eye with the use of a correcting lens. An eye which is accompanied by a limitation in the fields of vision such that the widest diameter of the visual field subtends an angle no greater than 20 degrees shall be considered for purposes of this paragraph as having a central visual acuity of 20/200 or less. The provisions of paragraphs (2)(A), (2)(B), (3), (4), (5), and (6) of section 423(d) of this title shall be applied for purposes of determining whether an individual is under a disability within the meaning of the first sentence of this paragraph in the same manner as they are applied for purposes of paragraph (1) of such section. Nothing in this subchapter shall be construed as authorizing the Commissioner of Social Security or any other officer or employee of the United States to interfere in any way with the practice of medicine or with relationships between practitioners of medicine and their patients, or to exercise any supervision or control over the administration or operation of any hospital. + +(i) (2) (A) The term “ period of disability ” means a continuous period (beginning and ending as hereinafter provided in this subsection) during which an individual was under a disability (as defined in paragraph (1)), but only if such period is of not less than five full calendar months' duration or such individual was entitled to benefits under section 423 of this title for one or more months in such period. (B) No period of disability shall begin as to any individual unless such individual files an application for a disability determination with respect to such period; and no such period shall begin as to any individual after such individual attains retirement age (as defined in subsection (l)). In the case of a deceased individual, the requirement of an application under the preceding sentence may be satisfied by an application for a disability determination filed with respect to such individual within 3 months after the month in which he died. (C) A period of disability shall begin— (i) on the day the disability began, but only if the individual satisfies the requirements of paragraph (3) on such day; or (ii) if such individual does not satisfy the requirements of paragraph (3) on such day, then on the first day of the first quarter thereafter in which he satisfies such requirements. (D) A period of disability shall end with the close of whichever of the following months is the earlier: (i) the month preceding the month in which the individual attains retirement age (as defined in subsection (l)), or (ii) the month preceding (I) the termination month (as defined in section 423(a)(1) of this title ), or, if earlier (II) the first month for which no benefit is payable by reason of section 423(e) of this title , where no benefit is payable for any of the succeeding months during the 36-month period referred to in such section. The provisions set forth in section 423(f) of this title with respect to determinations of whether entitlement to benefits under this subchapter or subchapter XVIII based on the disability of any individual is terminated (on the basis of a finding that the physical or mental impairment on the basis of which such benefits are provided has ceased, does not exist, or is not disabling) shall apply in the same manner and to the same extent with respect to determinations of whether a period of disability has ended (on the basis of a finding that the physical or mental impairment on the basis of which the finding of disability was made has ceased, does not exist, or is not disabling). (E) Except as is otherwise provided in subparagraph (F), no application for a disability determination which is filed more than 12 months after the month prescribed by subparagraph (D) as the month in which the period of disability ends (determined without regard to subparagraph (B) and this subparagraph) shall be accepted as an application for purposes of this paragraph. (F) An application for a disability determination which is filed more than 12 months after the month prescribed by subparagraph (D) as the month in which the period of disability ends (determined without regard to subparagraphs (B) and (E)) shall be accepted as an application for purposes of this paragraph if— (i) in the case of an application filed by or on behalf of an individual with respect to a disability which ends after January 1968, such application is filed not more than 36 months after the month in which such disability ended, such individual is alive at the time the application is filed, and the Commissioner of Social Security finds in accordance with regulations prescribed by the Commissioner that the failure of such individual to file an application for a disability determination within the time specified in subparagraph (E) was attributable to a physical or mental condition of such individual which rendered him incapable of executing such an application, and (ii) in the case of an application filed by or on behalf of an individual with respect to a period of disability which ends in or before January 1968— (I) such application is filed not more than 12 months after January 1968, (II) a previous application for a disability determination has been filed by or on behalf of such individual (1) in or before January 1968, and (2) not more than 36 months after the month in which his disability ended, and (III) the Commissioner of Social Security finds in accordance with regulations prescribed by the Commissioner, that the failure of such individual to file an application within the then specified time period was attributable to a physical or mental condition of such individual which rendered him incapable of executing such an application. In making a determination under this subsection, with respect to the disability or period of disability of any individual whose application for a determination thereof is accepted solely by reason of the provisions of this subparagraph (F), the provisions of this subsection (other than the provisions of this subparagraph) shall be applied as such provisions are in effect at the time such determination is made. (G) An application for a disability determination filed before the first day on which the applicant satisfies the requirements for a period of disability under this subsection shall be deemed a valid application (and shall be deemed to have been filed on such first day) only if the applicant satisfies the requirements for a period of disability before the Commissioner of Social Security makes a final decision on the application and no request under section 405(b) of this title for notice and opportunity for a hearing thereon is made or, if such a request is made, before a decision based upon the evidence adduced at the hearing is made (regardless of whether such decision becomes the final decision of the Commissioner of Social Security). + +(i) (3) The requirements referred to in clauses (i) and (ii) of paragraph (2)(C) of this subsection are satisfied by an individual with respect to any quarter only if— (A) he would have been a fully insured individual (as defined in section 414 of this title ) had he attained age 62 and filed application for benefits under section 402(a) of this title on the first day of such quarter; and (B) (i) he had not less than 20 quarters of coverage during the 40-quarter period which ends with such quarter, or (ii) if such quarter ends before he attains (or would attain) age 31, not less than one-half (and not less than 6) of the quarters during the period ending with such quarter and beginning after he attained the age of 21 were quarters of coverage, or (if the number of quarters in such period is less than 12) not less than 6 of the quarters in the 12-quarter period ending with such quarter were quarters of coverage, or (iii) in the case of an individual (not otherwise insured under clause (i)) who, by reason of clause (ii), had a prior period of disability that began during a period before the quarter in which he or she attained age 31, not less than one-half of the quarters beginning after such individual attained age 21 and ending with such quarter are quarters of coverage, or (if the number of quarters in such period is less than 12) not less than 6 of the quarters in the 12-quarter period ending with such quarter are quarters of coverage; except that the provisions of subparagraph (B) of this paragraph shall not apply in the case of an individual who is blind (within the meaning of “ blindness ” as defined in paragraph (1)). For purposes of subparagraph (B) of this paragraph, when the number of quarters in any period is an odd number, such number shall be reduced by one, and a quarter shall not be counted as part of any period if any part of such quarter was included in a prior period of disability unless such quarter was a quarter of coverage. + +(l) Retirement age (1) The term “ retirement age ” means— (A) with respect to an individual who attains early retirement age (as defined in paragraph (2)) before January 1, 2000 , 65 years of age; (B) with respect to an individual who attains early retirement age after December 31, 1999 , and before January 1, 2005 , 65 years of age plus the number of months in the age increase factor (as determined under paragraph (3)) for the calendar year in which such individual attains early retirement age; (C) with respect to an individual who attains early retirement age after December 31, 2004 , and before January 1, 2017 , 66 years of age; (D) with respect to an individual who attains early retirement age after December 31, 2016 , and before January 1, 2022 , 66 years of age plus the number of months in the age increase factor (as determined under paragraph (3)) for the calendar year in which such individual attains early retirement age; and (E) with respect to an individual who attains early retirement age after December 31, 2021 , 67 years of age. (2) The term “ early retirement age ” means age 62 in the case of an old-age, wife' s, or husband' s insurance benefit, and age 60 in the case of a widow' s or widower' s insurance benefit. (3) The age increase factor for any individual who attains early retirement age in a calendar year within the period to which subparagraph (B) or (D) of paragraph (1) applies shall be determined as follows: (A) With respect to an individual who attains early retirement age in the 5-year period consisting of the calendar years 2000 through 2004, the age increase factor shall be equal to two-twelfths of the number of months in the period beginning with January 2000 and ending with December of the year in which the individual attains early retirement age . (B) With respect to an individual who attains early retirement age in the 5-year period consisting of the calendar years 2017 through 2021, the age increase factor shall be equal to two-twelfths of the number of months in the period beginning with January 2017 and ending with December of the year in which the individual attains early retirement age . diff --git a/tests/data/track_b/insured_status_sources/lii_usc_42_423_excerpts.txt b/tests/data/track_b/insured_status_sources/lii_usc_42_423_excerpts.txt new file mode 100644 index 000000000..d69eae25f --- /dev/null +++ b/tests/data/track_b/insured_status_sources/lii_usc_42_423_excerpts.txt @@ -0,0 +1 @@ +(c) (1) An individual shall be insured for disability insurance benefits in any month if— (A) he would have been a fully insured individual (as defined in section 414 of this title ) had he attained age 62 and filed application for benefits under section 402(a) of this title on the first day of such month, and (B) (i) he had not less than 20 quarters of coverage during the 40-quarter period which ends with the quarter in which such month occurred, or (ii) if such month ends before the quarter in which he attains (or would attain) age 31, not less than one-half (and not less than 6) of the quarters during the period ending with the quarter in which such month occurred and beginning after he attained the age of 21 were quarters of coverage, or (if the number of quarters in such period is less than 12) not less than 6 of the quarters in the 12-quarter period ending with such quarter were quarters of coverage, or (iii) in the case of an individual (not otherwise insured under clause (i)) who, by reason of section 416(i)(3)(B)(ii) of this title , had a prior period of disability that began during a period before the quarter in which he or she attained age 31, not less than one-half of the quarters beginning after such individual attained age 21 and ending with the quarter in which such month occurs are quarters of coverage, or (if the number of quarters in such period is less than 12) not less than 6 of the quarters in the 12-quarter period ending with such quarter are quarters of coverage; except that the provisions of subparagraph (B) of this paragraph shall not apply in the case of an individual who is blind (within the meaning of “blindness” as defined in section 416(i)(1) of this title ). For purposes of subparagraph (B) of this paragraph, when the number of quarters in any period is an odd number, such number shall be reduced by one, and a quarter shall not be counted as part of any period if any part of such quarter was included in a period of disability unless such quarter was a quarter of coverage. diff --git a/tests/data/track_b/insured_status_sources/manifest.json b/tests/data/track_b/insured_status_sources/manifest.json new file mode 100644 index 000000000..2cedc1b2e --- /dev/null +++ b/tests/data/track_b/insured_status_sources/manifest.json @@ -0,0 +1,601 @@ +{ + "schema_version": 1, + "purpose": "Track B insured-status statutory conformance; published and invented cases only, no population data", + "capture_formats": { + "http_body": "Complete decoded HTTP response body, unchanged from the staged capture.", + "browser_text": "Rendered document text checked against the served page during staging; served_bodies pins the complete HTTP response.", + "http_text_excerpt": "Cited paragraphs of staged LII HTTP bodies after stripping tags, decoding entities, collapsing whitespace and straightening apostrophes; served_bodies pins each original complete response." + }, + "sources": [ + { + "file": "ecfr_20cfr404_subpart_b.xml", + "bytes": 51316, + "sha256": "9b07c75507015c2944ca4f19dc6a8b2fffc0e2c6c0fb31b3b8d58c65a3424dfd", + "id": "ecfr_20cfr404_subpart_b", + "citation": "20 CFR part 404 subpart B (eCFR, as of 2026-10-07)", + "url": "https://www.ecfr.gov/api/versioner/v1/full/2026-10-07/title-20.xml?part=404&subpart=B", + "retrieved_at_utc": "2026-10-21T13:57:36Z", + "capture": "http_body" + }, + { + "file": "lii_usc_42_413_excerpts.txt", + "bytes": 9494, + "sha256": "b45a823d4376fbb41f40acf31b5df62284afcdf7373c84491bb08df54abfad44", + "id": "lii_usc_42_413", + "citation": "42 U.S.C. 413 (Legal Information Institute)", + "url": "https://www.law.cornell.edu/uscode/text/42/413", + "retrieved_at_utc": "2026-10-21T13:57:14Z", + "capture": "http_text_excerpt", + "served_bodies": [ + { + "url": "https://www.law.cornell.edu/uscode/text/42/413", + "bytes": 113691, + "sha256": "2dc803f32773ee70e257a7de9a04ccdd04018f55d42078b93bec198bcd832cd3" + } + ] + }, + { + "file": "lii_usc_42_414_excerpts.txt", + "bytes": 2615, + "sha256": "deca2cfea26a61b37b847f4cd23d4820c362b6e5644622d50b9b6ee784b6fc24", + "id": "lii_usc_42_414", + "citation": "42 U.S.C. 414 (Legal Information Institute)", + "url": "https://www.law.cornell.edu/uscode/text/42/414", + "retrieved_at_utc": "2026-10-21T13:57:15Z", + "capture": "http_text_excerpt", + "served_bodies": [ + { + "url": "https://www.law.cornell.edu/uscode/text/42/414", + "bytes": 63944, + "sha256": "731e1dbc8648c689d2d97546980739a1a53477da0669d566d3d32ec9f3966a2d" + } + ] + }, + { + "file": "lii_usc_42_416_excerpts.txt", + "bytes": 11545, + "sha256": "3c5e7d55166dc8a27625c0c926ded03d38d074f23cc6daf88de1cae4dd346222", + "id": "lii_usc_42_416", + "citation": "42 U.S.C. 416 (Legal Information Institute)", + "url": "https://www.law.cornell.edu/uscode/text/42/416", + "retrieved_at_utc": "2026-10-21T13:57:18Z", + "capture": "http_text_excerpt", + "served_bodies": [ + { + "url": "https://www.law.cornell.edu/uscode/text/42/416", + "bytes": 288079, + "sha256": "bd04463b757e1358b1cbf6bc942c2593d7be96d5ca297094ebba11bd107602db" + } + ] + }, + { + "file": "lii_usc_42_423_excerpts.txt", + "bytes": 2044, + "sha256": "c0db1ea77f2d66910fa5eb7d2fdb9bd37e2f8b31ffc0a3d8a5298a384e277a61", + "id": "lii_usc_42_423", + "citation": "42 U.S.C. 423 (Legal Information Institute)", + "url": "https://www.law.cornell.edu/uscode/text/42/423", + "retrieved_at_utc": "2026-10-21T13:57:17Z", + "capture": "http_text_excerpt", + "served_bodies": [ + { + "url": "https://www.law.cornell.edu/uscode/text/42/423", + "bytes": 250339, + "sha256": "5168d384819acdcc672139f5d3b9e97ffdcb67c0bcad6f6a879052a66af44d2a" + } + ] + }, + { + "file": "poms_rs_00301_000_toc.html", + "bytes": 29635, + "sha256": "23d5cd4907d30360336f43b95a132241b1efc2a544b3d5cb4e9854d85ced3f62", + "id": "poms_rs_00301_000_toc", + "citation": "POMS RS 00301.000", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301000", + "retrieved_at_utc": "2026-10-21T13:56:14Z", + "capture": "http_body", + "poms_transmittal": null, + "title": "RS 00301.000 - Retirement, Survivors and Disability Requirements - Table of Contents - 09/04/2026", + "page_date": "09/04/2026" + }, + { + "file": "poms_rs_00301_101.html", + "bytes": 45244, + "sha256": "d7f1456ee6133790299468e4f5fd093711011e9e24032fff9bbb6cbfd5c2a6fc", + "id": "poms_rs_00301_101", + "citation": "POMS RS 00301.101", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301101", + "retrieved_at_utc": "2026-10-21T13:56:15Z", + "capture": "http_body", + "poms_transmittal": "TN 51 (10-23)", + "title": "RS 00301.101 - Insured Status — Overview - 08/09/2011", + "page_date": "08/09/2011" + }, + { + "file": "poms_rs_00301_102.html", + "bytes": 225887, + "sha256": "dee8220e70bfbe337a327d9f79ba9ece7743db7c2eb146254c62deed5827e754", + "id": "poms_rs_00301_102", + "citation": "POMS RS 00301.102", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301102", + "retrieved_at_utc": "2026-10-21T13:56:16Z", + "capture": "http_body", + "poms_transmittal": "TN 64 (09-26)", + "title": "RS 00301.102 - Additional Requirements for Alien Workers- Social Security Protection Act of 2004 - 10/04/2023", + "page_date": "10/04/2023" + }, + { + "file": "poms_rs_00301_105.html", + "bytes": 29489, + "sha256": "6f7920fae7eac9589ccb05bd3e51b85f080bc46646096f3feafe9baf1681d88e", + "id": "poms_rs_00301_105", + "citation": "POMS RS 00301.105", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301105", + "retrieved_at_utc": "2026-10-21T13:56:17Z", + "capture": "http_body", + "poms_transmittal": "TN 48 (10-23)", + "title": "RS 00301.105 - Fully Insured Status - 11/12/2010", + "page_date": "11/12/2010" + }, + { + "file": "poms_rs_00301_106.html", + "bytes": 26367, + "sha256": "2a85835c78b5c94e7a3e921f23d0b18461fa4a7ff36c2700861793db9ef4c011", + "id": "poms_rs_00301_106", + "citation": "POMS RS 00301.106", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301106", + "retrieved_at_utc": "2026-10-21T13:56:19Z", + "capture": "http_body", + "poms_transmittal": "TN 45 (10-23)", + "title": "RS 00301.106 - Deemed Fully Insured - 10/06/2023", + "page_date": "10/06/2023" + }, + { + "file": "poms_rs_00301_107.html", + "bytes": 25021, + "sha256": "c80dde8fbbda1602c02ba059b8732d090ea1546285688fb257d82476f06b2cbb", + "id": "poms_rs_00301_107", + "citation": "POMS RS 00301.107", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301107", + "retrieved_at_utc": "2026-10-21T13:56:20Z", + "capture": "http_body", + "poms_transmittal": "TN 20 (05-11)", + "title": "RS 00301.107 - Identification and Development of Deemed Fully Insured Status - 07/19/2002", + "page_date": "07/19/2002" + }, + { + "file": "poms_rs_00301_110.html", + "bytes": 20502, + "sha256": "6caf9a505c7c2aca23ae818dd4008c084c0527051624d2af8491195b0a681cd0", + "id": "poms_rs_00301_110", + "citation": "POMS RS 00301.110", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301110", + "retrieved_at_utc": "2026-10-21T13:56:21Z", + "capture": "http_body", + "poms_transmittal": "TN 54 (10-23)", + "title": "RS 00301.110 - Currently Insured Status - 08/18/2004", + "page_date": "08/18/2004" + }, + { + "file": "poms_rs_00301_120.html", + "bytes": 28986, + "sha256": "12b6fad03a284e48507aae5af0055610d1085d2b9b7de14bf6d6693d9c8d0023", + "id": "poms_rs_00301_120", + "citation": "POMS RS 00301.120", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301120", + "retrieved_at_utc": "2026-10-21T13:56:22Z", + "capture": "http_body", + "poms_transmittal": "TN 50 (10-23)", + "title": "RS 00301.120 - DIB Insured Status - 08/18/2004", + "page_date": "08/18/2004" + }, + { + "file": "poms_rs_00301_122.html", + "bytes": 18565, + "sha256": "0fc39a8f5c8d9b2408b5dad8bd436de52b9b615a0ad6c187f467ba73b9d8568c", + "id": "poms_rs_00301_122", + "citation": "POMS RS 00301.122", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301122", + "retrieved_at_utc": "2026-10-21T13:56:23Z", + "capture": "http_body", + "poms_transmittal": "TN 20 (05-11)", + "title": "RS 00301.122 - Relationship Between Period of Disability and Insured Status - 01/23/2015", + "page_date": "01/23/2015" + }, + { + "file": "poms_rs_00301_130.html", + "bytes": 22285, + "sha256": "3dcdabefbb6fcd2e4529ea94a6a5fcf562aa51e65bf32e9fbe2a1ca8bad07e26", + "id": "poms_rs_00301_130", + "citation": "POMS RS 00301.130", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301130", + "retrieved_at_utc": "2026-10-21T13:56:25Z", + "capture": "http_body", + "poms_transmittal": "TN 42 (10-23)", + "title": "RS 00301.130 - Freeze Insured Status Requirements - 08/18/2004", + "page_date": "08/18/2004" + }, + { + "file": "poms_rs_00301_131.html", + "bytes": 17706, + "sha256": "a8cc684fe1ddd60fd7e150bb897f2f3ee6d8a60038fee704e68e3836d499f7e8", + "id": "poms_rs_00301_131", + "citation": "POMS RS 00301.131", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301131", + "retrieved_at_utc": "2026-10-21T13:56:26Z", + "capture": "http_body", + "poms_transmittal": "TN 20 (05-11)", + "title": "RS 00301.131 - Use of Railroad (RR) Compensation and Military Service (MS) Credits for Freeze Insured Status - 01/23/2015", + "page_date": "01/23/2015" + }, + { + "file": "poms_rs_00301_132.html", + "bytes": 23977, + "sha256": "d65fc3cba91bdc168ee4ae903c6b1b16d5e5b0b93949ca0cbc10740aa27f3a0c", + "id": "poms_rs_00301_132", + "citation": "POMS RS 00301.132", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301132", + "retrieved_at_utc": "2026-10-21T13:56:27Z", + "capture": "http_body", + "poms_transmittal": "TN 44 (10-23)", + "title": "RS 00301.132 - Relationship Between Freeze Insured Status and Disability Insurance Benefits (DIB) Insured Status - 10/06/2023", + "page_date": "10/06/2023" + }, + { + "file": "poms_rs_00301_140.html", + "bytes": 38536, + "sha256": "76a8308bbb8be90097040dc4fa91f10579940689738c5704212ae82266489954", + "id": "poms_rs_00301_140", + "citation": "POMS RS 00301.140", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301140", + "retrieved_at_utc": "2026-10-21T13:56:28Z", + "capture": "http_body", + "poms_transmittal": "TN 46 (10-23)", + "title": "RS 00301.140 - Special Insured Status for Disability Before Age 31 - 04/15/2022", + "page_date": "04/15/2022" + }, + { + "file": "poms_rs_00301_147.html", + "bytes": 53524, + "sha256": "39ec334cac61f5abb359345b8358feee918f8df7a23e8b85b45b86a2063f7159", + "id": "poms_rs_00301_147", + "citation": "POMS RS 00301.147", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301147", + "retrieved_at_utc": "2026-10-21T13:56:29Z", + "capture": "http_body", + "poms_transmittal": "TN 57 (10-23)", + "title": "RS 00301.147 - Special Insured Status Requirements for Subsequent Periods of Disability - NH Over Age 31 - 04/21/2023", + "page_date": "04/21/2023" + }, + { + "file": "poms_rs_00301_148.html", + "bytes": 28174, + "sha256": "11fe33e7ff6840eff071fd14d629cda8790ebe3af77b5c762f4e0cca77d900eb", + "id": "poms_rs_00301_148", + "citation": "POMS RS 00301.148", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301148", + "retrieved_at_utc": "2026-10-21T13:56:30Z", + "capture": "http_body", + "poms_transmittal": "TN 49 (10-23)", + "title": "RS 00301.148 - Date Last Insured (DLI) - 01/13/2006", + "page_date": "01/13/2006" + }, + { + "file": "poms_rs_00301_149.html", + "bytes": 16605, + "sha256": "ab96b715a7add620f3d40141f6569592c6c7f95358d5b12e758246014e6de9a8", + "id": "poms_rs_00301_149", + "citation": "POMS RS 00301.149", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301149", + "retrieved_at_utc": "2026-10-21T13:56:32Z", + "capture": "http_body", + "poms_transmittal": "TN 20 (05-11)", + "title": "RS 00301.149 - SSA-1164 Exhibit of Special Insured Status Worksheet - 06/23/2011", + "page_date": "06/23/2011" + }, + { + "file": "poms_rs_00301_150.html", + "bytes": 24115, + "sha256": "b2e17c812d4c63c84d72c0286c601d95ed11721ddbe7181681749bdc39440342", + "id": "poms_rs_00301_150", + "citation": "POMS RS 00301.150", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301150", + "retrieved_at_utc": "2026-10-21T13:56:33Z", + "capture": "http_body", + "poms_transmittal": "TN 63 (04-26)", + "title": "RS 00301.150 - Insured Status for Statutory Blindness - 10/12/2023", + "page_date": "10/12/2023" + }, + { + "file": "poms_rs_00301_160.html", + "bytes": 28009, + "sha256": "58d9d65773b3c9bff2f69b102463aed24d86f526790a75f9fd062146e826e5e4", + "id": "poms_rs_00301_160", + "citation": "POMS RS 00301.160", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301160", + "retrieved_at_utc": "2026-10-21T13:56:34Z", + "capture": "http_body", + "poms_transmittal": "TN 53 (10-23)", + "title": "RS 00301.160 - Insured Status Based on Medicare Qualified Government Employment - 05/26/2011", + "page_date": "05/26/2011" + }, + { + "file": "poms_rs_00301_161.html", + "bytes": 19296, + "sha256": "b393d1538b7edf8e1ffeda1e94441bcb80d5072137de9045f81b8085e41a0883", + "id": "poms_rs_00301_161", + "citation": "POMS RS 00301.161", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301161", + "retrieved_at_utc": "2026-10-21T13:56:35Z", + "capture": "http_body", + "poms_transmittal": "TN 20 (05-11)", + "title": "RS 00301.161 - Part A Premium Reduction for Individuals with at Least 30 Quarters of Coverage (QC) - 05/26/2011", + "page_date": "05/26/2011" + }, + { + "file": "poms_rs_00301_200.html", + "bytes": 18282, + "sha256": "bb8fc3d4a7ace6e75bfbf87235f8290b3ff67d38d4b4bb3fe3d44da9f6dfa829", + "id": "poms_rs_00301_200", + "citation": "POMS RS 00301.200", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301200", + "retrieved_at_utc": "2026-10-21T13:56:36Z", + "capture": "http_body", + "poms_transmittal": "TN 20 (05-11)", + "title": "RS 00301.200 - Quarters of Coverage (QC) - 07/25/1996", + "page_date": "07/25/1996" + }, + { + "file": "poms_rs_00301_210.html", + "bytes": 17911, + "sha256": "a8b416a2756e8552dcb4f31410e871b077821cc078c098edb7d2db0a5518169a", + "id": "poms_rs_00301_210", + "citation": "POMS RS 00301.210", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301210", + "retrieved_at_utc": "2026-10-21T13:56:37Z", + "capture": "http_body", + "poms_transmittal": "TN 20 (05-11)", + "title": "RS 00301.210 - Crediting Quarters of Coverage (QC) - 05/26/2011", + "page_date": "05/26/2011" + }, + { + "file": "poms_rs_00301_220.html", + "bytes": 17815, + "sha256": "e83e25303b2d3aec68f9c193c6068dba992ee94fa51761d478fa6674dc7cafb4", + "id": "poms_rs_00301_220", + "citation": "POMS RS 00301.220", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301220", + "retrieved_at_utc": "2026-10-21T13:56:39Z", + "capture": "http_body", + "poms_transmittal": "TN 20 (05-11)", + "title": "RS 00301.220 - Crediting of Self-Employment Income (SEI) to Calendar Years - 06/14/2013", + "page_date": "06/14/2013" + }, + { + "file": "poms_rs_00301_230.html", + "bytes": 20419, + "sha256": "f4f6d7c00a7041b3c81ec0f7c65bd38c0edd1598ee8862354926d70ac2ea82eb", + "id": "poms_rs_00301_230", + "citation": "POMS RS 00301.230", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301230", + "retrieved_at_utc": "2026-10-21T13:56:40Z", + "capture": "http_body", + "poms_transmittal": "TN 58 (11-23)", + "title": "RS 00301.230 - Assignment of Quarters of Coverage (QC) - 11/01/2023", + "page_date": "11/01/2023" + }, + { + "file": "poms_rs_00301_240.html", + "bytes": 19235, + "sha256": "3c484231ef09d30c481ab91f90c39d42e5418d7171f48a50f8fcfe65bec9f9a0", + "id": "poms_rs_00301_240", + "citation": "POMS RS 00301.240", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301240", + "retrieved_at_utc": "2026-10-21T13:56:41Z", + "capture": "http_body", + "poms_transmittal": "TN 19 (05-11)", + "title": "RS 00301.240 - When a Calendar Quarter cannot be a Quarter of Coverage (QC) - 05/17/2011", + "page_date": "05/17/2011" + }, + { + "file": "poms_rs_00301_250.html", + "bytes": 43627, + "sha256": "b6506e3fd2e807812f6e3ff0570473c4e3f5032fc6e870b78d782fe45d130a64", + "id": "poms_rs_00301_250", + "citation": "POMS RS 00301.250", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301250", + "retrieved_at_utc": "2026-10-21T13:56:42Z", + "capture": "http_body", + "poms_transmittal": "TN 62 (11-25)", + "title": "RS 00301.250 - Chart of Increment Amounts - 11/21/2025", + "page_date": "11/21/2025" + }, + { + "file": "poms_rs_00301_301.html", + "bytes": 17542, + "sha256": "18c0f696142080d2bf52db0167ff28e7381c7d3655fc6e698c51d66f07e32175", + "id": "poms_rs_00301_301", + "citation": "POMS RS 00301.301", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301301", + "retrieved_at_utc": "2026-10-21T13:56:43Z", + "capture": "http_body", + "poms_transmittal": "TN 41 (10-23)", + "title": "RS 00301.301 - Quarters of Coverage (QC) before 1978 - 10/05/2023", + "page_date": "10/05/2023" + }, + { + "file": "poms_rs_00301_310.html", + "bytes": 20008, + "sha256": "04281c06db99c4665d15eac7a4f49157a7261ad51e6654b7b2cb057971240ecb", + "id": "poms_rs_00301_310", + "citation": "POMS RS 00301.310", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301310", + "retrieved_at_utc": "2026-10-21T13:56:44Z", + "capture": "http_body", + "poms_transmittal": "TN 21 (06-11)", + "title": "RS 00301.310 - Wage Quarters of Coverage (QC) - 06/23/2011", + "page_date": "06/23/2011" + }, + { + "file": "poms_rs_00301_315.html", + "bytes": 26495, + "sha256": "3dbb0b1b79fac49da5d829ddab8ee69eac83cb121a664763236e8aeb7e6726f8", + "id": "poms_rs_00301_315", + "citation": "POMS RS 00301.315", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301315", + "retrieved_at_utc": "2026-10-21T13:56:46Z", + "capture": "http_body", + "poms_transmittal": "TN 43 (10-23)", + "title": "RS 00301.315 - Simplified Method of Determining Quarters of Coverage (QC) for 1937 - 1950 Period - 10/06/2023", + "page_date": "10/06/2023" + }, + { + "file": "poms_rs_00301_320.html", + "bytes": 21028, + "sha256": "8e3fb43e37ce710dc20066962958be937c0106c8840cd020929f9d820f08359b", + "id": "poms_rs_00301_320", + "citation": "POMS RS 00301.320", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301320", + "retrieved_at_utc": "2026-10-21T13:56:47Z", + "capture": "http_body", + "poms_transmittal": "TN 55 (10-23)", + "title": "RS 00301.320 - Assignment of Quarters of Coverage (QC) based on Wages for Agricultural Labor before 1978 - 10/16/2023", + "page_date": "10/16/2023" + }, + { + "file": "poms_rs_00301_325.html", + "bytes": 19797, + "sha256": "1cc2c240b3dff30fad0c2954692e588dce39b67f363634b42124541ce5201b5c", + "id": "poms_rs_00301_325", + "citation": "POMS RS 00301.325", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301325", + "retrieved_at_utc": "2026-10-21T13:56:48Z", + "capture": "http_body", + "poms_transmittal": "TN 40 (10-23)", + "title": "RS 00301.325 - Flexible Assignment of Quarters of Coverage (QC) based on Wages for Agricultural Labor - 10/05/2023", + "page_date": "10/05/2023" + }, + { + "file": "poms_rs_00301_340.html", + "bytes": 21601, + "sha256": "e9a10a768e10bd494ae9d161491bf22b46b25c52880e9ea4279da6dfcdb375b7", + "id": "poms_rs_00301_340", + "citation": "POMS RS 00301.340", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301340", + "retrieved_at_utc": "2026-10-21T13:56:49Z", + "capture": "http_body", + "poms_transmittal": "TN 56 (10-23)", + "title": "RS 00301.340 - Self-Employment Quarters of Coverage (QC) before 1978 - 10/17/2023", + "page_date": "10/17/2023" + }, + { + "file": "poms_rs_00301_345.html", + "bytes": 33788, + "sha256": "510a08ddf0ffdbf8fdfd664954ec2bb29bacf17de96b8f9882180d107210188e", + "id": "poms_rs_00301_345", + "citation": "POMS RS 00301.345", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301345", + "retrieved_at_utc": "2026-10-21T13:56:50Z", + "capture": "http_body", + "poms_transmittal": "TN 47 (10-23)", + "title": "RS 00301.345 - Gift Quarters of Coverage (QC) - 10/06/2023", + "page_date": "10/06/2023" + }, + { + "file": "poms_rs_00301_350.html", + "bytes": 25890, + "sha256": "2512b0e0418b34030b1e415921f7932eafaf1401b68c333ec6862f4a2b796a40", + "id": "poms_rs_00301_350", + "citation": "POMS RS 00301.350", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301350", + "retrieved_at_utc": "2026-10-21T13:56:51Z", + "capture": "http_body", + "poms_transmittal": "TN 21 (06-11)", + "title": "RS 00301.350 - Quarters of Coverage (QC) Based on Railroad (RR) Compensation Before 1978 - 06/23/2011", + "page_date": "06/23/2011" + }, + { + "file": "poms_rs_00301_470.html", + "bytes": 17779, + "sha256": "5f1712b9e09fed921a04753759baeea904a22d1feb6dc0dbf3aae0167380c031", + "id": "poms_rs_00301_470", + "citation": "POMS RS 00301.470", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301470", + "retrieved_at_utc": "2026-10-21T13:56:52Z", + "capture": "http_body", + "poms_transmittal": "TN 39 (10-23)", + "title": "RS 00301.470 - Deemed Fully Insured Status for World War II (WW II) Veterans - 10/05/2023", + "page_date": "10/05/2023" + }, + { + "file": "poms_rs_00301_475.html", + "bytes": 22360, + "sha256": "2f30f4f3997c757839f19ef1cd25c2c1dadc3e6f89455a5df5dace0954e74a1a", + "id": "poms_rs_00301_475", + "citation": "POMS RS 00301.475", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301475", + "retrieved_at_utc": "2026-10-21T13:56:54Z", + "capture": "http_body", + "poms_transmittal": "TN 38 (10-23)", + "title": "RS 00301.475 - Special Method of Determining Insured Status by Crediting Wage Quarters of Coverage (QC) on Earned Basis - 10/05/2023", + "page_date": "10/05/2023" + }, + { + "file": "poms_rs_00301_480.html", + "bytes": 21026, + "sha256": "b83438eea8b3b5e35451fd176a4e3d122aedec9f344d4b071e81a388a43e0d12", + "id": "poms_rs_00301_480", + "citation": "POMS RS 00301.480", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301480", + "retrieved_at_utc": "2026-10-21T13:56:55Z", + "capture": "http_body", + "poms_transmittal": "TN 37 (10-23)", + "title": "RS 00301.480 - Alternate Insured Status Test for NH's Under a Disability Before 1956 - 10/05/2023", + "page_date": "10/05/2023" + }, + { + "file": "poms_rs_00301_600.html", + "bytes": 19441, + "sha256": "3598400f77293b0d933abb53afcc4b22bacd4e0b5519af5400a0a6fbb78c56fb", + "id": "poms_rs_00301_600", + "citation": "POMS RS 00301.600", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301600", + "retrieved_at_utc": "2026-10-21T13:56:56Z", + "capture": "http_body", + "poms_transmittal": "TN 23 (07-11)", + "title": "RS 00301.600 - Election of Coverage by Vow-of-Poverty Order - 07/21/2011", + "page_date": "07/21/2011" + }, + { + "file": "poms_rs_00301_800.html", + "bytes": 17004, + "sha256": "f6fe4d8f7a00be6466bf95aae7252e19ea7b636b3405960ec49ef625b8ac73e2", + "id": "poms_rs_00301_800", + "citation": "POMS RS 00301.800", + "url": "https://secure.ssa.gov/poms.nsf/lnx/0300301800", + "retrieved_at_utc": "2026-10-21T13:56:57Z", + "capture": "http_body", + "poms_transmittal": "TN 14 (04-89)", + "title": "RS 00301.800 - Quarters of Coverage Requirements - Exhibit - 08/10/2012", + "page_date": "08/10/2012" + }, + { + "file": "ssa_oact_qc.txt", + "bytes": 3332, + "sha256": "27edf85daeef0f2d4235c826771d29b89a941fbf4400fa99df829c4de581f74b", + "id": "ssa_oact_qc", + "citation": "SSA Office of the Chief Actuary, Quarter of Coverage", + "url": "https://www.ssa.gov/oact/cola/QC.html", + "retrieved_at_utc": "2026-10-21T13:59:17Z", + "capture": "browser_text", + "note": "Rendered main text of the page, fetched from the ssa.gov origin in the Claude desktop in-app browser (www.ssa.gov answers curl with HTTP 403); file bytes equal the UTF-8 of the rendered text, whose SHA-256 was computed in the page.", + "served_bodies": [ + { + "url": "https://www.ssa.gov/oact/cola/QC.html", + "bytes": 39454, + "sha256": "1e864536eb0b975f8f4d82d1ac806f57c285ab1dc2d8f9f03d34976caa02b6e7" + } + ] + } + ] +} diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_000_toc.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_000_toc.html new file mode 100644 index 000000000..15b27c310 --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_000_toc.html @@ -0,0 +1,499 @@ + + +SSA - POMS: RS 00301.000 - Retirement, Survivors and Disability Requirements - Table of Contents - 09/04/2026 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

RS 00301.000 Retirement, Survivors and Disability Requirements

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Subchapter Table of Contents
Section Latest
Transmittal
RS 00301.101Insured Status — OverviewTN 51 10-23
RS 00301.102Additional Requirements for Alien Workers- Social Security Protection Act of 2004TN 64 09-26
RS 00301.105Fully Insured StatusTN 48 10-23
RS 00301.106Deemed Fully InsuredTN 45 10-23
RS 00301.107Identification and Development of Deemed Fully Insured StatusTN 20 05-11
RS 00301.110Currently Insured StatusTN 54 10-23
RS 00301.120DIB Insured StatusTN 50 10-23
RS 00301.122Relationship Between Period of Disability and Insured StatusTN 20 05-11
RS 00301.130Freeze Insured Status RequirementsTN 42 10-23
RS 00301.131Use of Railroad (RR) Compensation and Military Service (MS) Credits for Freeze Insured + StatusTN 20 05-11
RS 00301.132Relationship Between Freeze Insured Status and Disability Insurance Benefits (DIB) + Insured StatusTN 44 10-23
RS 00301.140Special Insured Status for Disability Before Age 31TN 46 10-23
RS 00301.147Special Insured Status Requirements for Subsequent Periods of Disability - NH Over + Age 31TN 57 10-23
RS 00301.148Date Last Insured (DLI)TN 49 10-23
RS 00301.149SSA-1164 Exhibit of Special Insured Status WorksheetTN 20 05-11
RS 00301.150Insured Status for Statutory BlindnessTN 63 04-26
RS 00301.160Insured Status Based on Medicare Qualified Government EmploymentTN 53 10-23
RS 00301.161Part A Premium Reduction for Individuals with at Least 30 Quarters of Coverage (QC)TN 20 05-11
RS 00301.200Quarters of Coverage (QC)TN 20 05-11
RS 00301.210Crediting Quarters of Coverage (QC)TN 20 05-11
RS 00301.220Crediting of Self-Employment Income (SEI) to Calendar YearsTN 20 05-11
RS 00301.230Assignment of Quarters of Coverage (QC)TN 58 11-23
RS 00301.240When a Calendar Quarter cannot be a Quarter of Coverage (QC)TN 19 05-11
RS 00301.250Chart of Increment AmountsTN 62 11-25
RS 00301.301Quarters of Coverage (QC) before 1978TN 41 10-23
RS 00301.310Wage Quarters of Coverage (QC)TN 21 06-11
RS 00301.315Simplified Method of Determining Quarters of Coverage (QC) for 1937 - 1950 PeriodTN 43 10-23
RS 00301.320Assignment of Quarters of Coverage (QC) based on Wages for Agricultural Labor before + 1978TN 55 10-23
RS 00301.325Flexible Assignment of Quarters of Coverage (QC) based on Wages for Agricultural LaborTN 40 10-23
RS 00301.340Self-Employment Quarters of Coverage (QC) before 1978TN 56 10-23
RS 00301.345Gift Quarters of Coverage (QC)TN 47 10-23
RS 00301.350Quarters of Coverage (QC) Based on Railroad (RR) Compensation Before 1978TN 21 06-11
RS 00301.470Deemed Fully Insured Status for World War II (WW II) VeteransTN 39 10-23
RS 00301.475Special Method of Determining Insured Status by Crediting Wage Quarters of Coverage + (QC) on Earned BasisTN 38 10-23
RS 00301.480Alternate Insured Status Test for NH's Under a Disability Before 1956TN 37 10-23
RS 00301.600Election of Coverage by Vow-of-Poverty OrderTN 23 07-11
SUMMARY OF REQUIREMENTS +
RS 00301.800Quarters of Coverage Requirements - ExhibitTN 14 04-89
+
+
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301000
RS 00301.000 - Retirement, Survivors and Disability Requirements - Table of Contents - 09/04/2026
+Batch run: 09/04/2026
+Rev:09/04/2026
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_101.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_101.html new file mode 100644 index 000000000..067cbb2ac --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_101.html @@ -0,0 +1,762 @@ + + +SSA - POMS: RS 00301.101 - Insured Status &mdash; Overview - 08/09/2011 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 51 (10-23)

+

RS 00301.101 Insured Status — Overview

+ + +
+
+

A. Introduction

+
+
+
+
+

1. What is insured status?

+
+
+

Insured status is the earnings requirement a number holder (NH) must meet in order + to establish entitlement to any type of benefit or a period of disability based on + their earnings record (e.g., retirement, disability or survivor’s insurance benefits).

+

 

+

To meet insured status, the NH must have the required number of earnings credits, + called “quarters of coverage” (QCs), on their earnings record. For certain benefits, + the QCs must be earned within a specific time frame. There are several different insured + status tests depending upon the type of benefit being sought. The table in RS 00301.101B of this section summarizes the various insured status tests.

+

 

+
+
+

NOTE: In addition, if the worker is an alien whose Social Security Number (SSN) was first + assigned on or after January 1, 2004, they must meet additional requirements under + Section 211 of the Social Security Protection Act of 2004 (Public Law 108-203) in + order to be fully or currently insured and to establish entitlement based on their + earnings. See RS 00301.102 for a full discussion of these requirements.

+
+
+

An alien worker whose SSN was assigned before January 1, 2004 is exempt from the requirements + of section 211 of the Social Security Protection Act, even if the SSN was not “work + authorized.”

+

 

+
+
+
+
+

2. Quarters of Coverage

+
+
+

The following table shows where to find more information about QCs:

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TopicReference
+

When a calendar quarter can be a QC for years after 1977

+
+

RS 00301.210 and RS 00301.250

+
+

QCs based in self-employment income

+
+

RS 00301.220

+
+

When a quarter can be a QC for years before 1978

+
+

RS 00301.301

+
+

Assignment of QCs: flexible assignment of QCs after 1977

+
+

RS 00301.230

+
+

When a calendar quarter cannot be a QC

+
+

RS 00301.240

+
+
+
+
+

NOTE: Subject to the rules in RS 00301.230 and RS 00301.240, a QC for a year after 1977 may be assigned to a calendar quarter in that year that + is most advantageous to the NH for the purposes of determining insured status.

+
+
+
+
+
+
+ +
+
+

B. Policy—types of insured status

+
+
+
+
+

1. Table of insured status tests

+
+
+

The following table summarizes the type(s) of insured status a Number Holder must + meet for each class of benefits:

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Status of the NH

+
+

Type of Benefit Sought

+
+

Then the NH must meet…

+
+

NH is living

+
+

Retirement Insurance Benefits (RIB)

+
+

Fully Insured status (RS 00301.105)

+
+

NH is living

+
+

Disability Insurance Benefits (DIB)

+
+

DIB Insured status. In general, DIB insured status means the NH must meet fully insured + status and a recent work test, such as 20/40 (RS 00301.120B.1) or Special Insured Status (RS 00301.140).

+ +

See RS 00301.120 for a discussion or DIB insured status.

+
+

NH is living

+ +

 

+
+

Period of Disability (i.e., “Freeze,” no cash benefits)

+
+

Freeze insured status. In general, this means the NH must meet fully insured status + and a recent work test, such as 20/40 (RS 00301.120B.1) or Special Insured Status (RS 00301.140).

+ +

See RS 00301.130 for a discussion of freeze insured status.

+
+

NH is living

+
+

Hospital Insurance based on end stage renal disease (ESRD), (R-HI)

+
+

Insured status for Medicare Part A for ESRD; i.e., fully insured status in RS 00301.105; or currently insured status in RS 00301.110.

+ +

(HI 00801.191C.2 and HI 00801.201.)

+
+

NH is living

+
+

Medicare for Qualified Government Employee (MQGE)

+
+

Insured status for hospital insurance (RS 00301.160 and HI 00801.410)

+
+

NH is living

+
+

On Record of Retired NH—Child’s benefits (RS 00202.001),

+
+

Fully Insured status

+
+

NH is living

+
+

On Record of Retired NH—Spouse benefits (RS 00202.001),

+
+

Fully Insured status (RS 00301.105) or Transitional Insured Status (RS 00202.015, RS 00202.020

+
+

NH is living

+
+

On Record of Disabled NH—Child’s benefits (RS 00203.001), Spouses benefits, including current and divorced spouses (RS 00202.001)

+
+

DIB Insured status. In general, DIB insured status means the NH must meet fully insured + status and a recent work test, such as 20/40 (RS 00301.120B.1) or Special Insured Status (RS 00301.140).

+ +

See RS 00301.120 for discussion of DIB insured status.

+
+

NH is deceased

+
+

Child’s benefits (RS 00203.001)

+
+

Fully insured status (RS 00301.105); or

+ +

Currently insured status

+ +

(RS 00301.110)

+
+

NH is deceased

+
+

Widow(er)’s benefits (RS 00207.001)

+
+

Fully insured status (RS 00301.105);

+
+

NH is deceased

+ +

 

+
+

Mother’s/father’s benefits

+ +

(RS 00208.001)

+
+

Fully insured status

+ +

(RS 00301.105); or

+ +

Currently insured status

+ +

(RS 00301.110)

+
+

NH is deceased

+
+

Parent’s Benefits (RS 00209.001)

+
+

Fully insured status

+ +

(RS 00301.105)

+
+

NH is deceased

+ +

 

+
+

Lump-Sum Death Payment

+ +

(RS 00210.001)

+ +

 

+
+

Fully insured status

+ +

(RS 00301.105); or

+ +

Currently insured status (RS 00301.110)

+
+
+

 

+
+
+
+
+

2. Deemed fully insured status

+
+
+

Certain employees of private nonprofit organizations who do not otherwise meet the + fully insured status test in RS 00301.105 are deemed “fully insured” for all Title II purposes, (including Medicare based on + End Stage Renal Disease in Section 226A of the SSAct) if the employee meets the requirements + in RS 00301.106.

+
+
+
+
+

3. Additional requirements for alien workers under the Social Security Protection Act + of 2004

+
+
+

Under Section 211 of the Social Security Protection Act of 2004, an alien worker must + meet additional requirements to be considered insured if their SSN was first assigned + on or after January 1, 2004. See RS 00301.102 for a full discussion of these requirements.

+
+
+
+
+ +
+
+

C. Policy—retirement age for determining insured status

+
+
+

Use the following table to determine the “retirement age” for insured status purposes. + NOTE: Do not use the “full retirement age” as defined in RS 00615.003 for determining insured status.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

If NH is...

+
+

and was born...

+
+

then retirement age is...

+
+

Female

+
+

any time

+
+

always age 62

+
+

Male

+
+

1/2/1913 or later

+
+

age 62

+
+

Male

+
+

1/2/1911 through 1/1/1913

+
+

deemed to have attained retirement age of 62 in 1975

+
+

Male

+
+

1/1/1911 or earlier

+
+

age 65

+
+
+
+
+
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301101
RS 00301.101 - Insured Status &mdash; Overview - 08/09/2011
+Batch run: 10/07/2026
+Rev:08/09/2011
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_102.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_102.html new file mode 100644 index 000000000..874187cbe --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_102.html @@ -0,0 +1,3545 @@ + + +SSA - POMS: RS 00301.102 - Additional Requirements for Alien Workers- Social Security Protection Act of 2004 - 10/04/2023 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 64 (09-26)

+

RS 00301.102 Additional Requirements for Alien Workers- Social Security Protection Act of 2004

+ + +
+
+

CITATIONS:

+
+
+ +
Section 211 of Public Law 108-203, 42 USC 414, 42 USC 423
+
+
+
+
+

A. Introduction

+
+
+

The Social Security Protection Act of 2004 (SSPA, or Public Law 108-203) was signed + into law on March 2, 2004. Under Section 211 of this legislation, certain alien workers + must meet additional requirements to be fully or currently insured and to establish + entitlement to benefits based on the alien's earnings. This law applies to Title II + benefits and Medicare based on End-Stage Renal Disease (ESRD).

+

The instructions on the SSPA are organized as follows:

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Topic

+
+

Subsection

+
+

Policy Provisions of Section 211 of the SSPA

+
+

RS 00301.102B

+
+

Policy interaction between Section 211 of the SSPA and other provisions affecting + payment/entitlement of aliens (lawful presence, alien nonpayment, removal, and totalization + provisions)

+
+

RS 00301.102C

+
+

Procedure development and determinations under Section 211 of the SSPA

+
+

RS 00301.102D

+
+

Procedure disallowance paragraphs

+
+

RS 00301.102E

+
+

Examples

+
+

RS 00301.102F

+
+

References

+
+

RS 00301.102G

+
+
+
+
+ +
+
+

B. Policy provisions of Section 211 of the SSPA

+
+
+
+
+

1. Who is subject to Section 211 of the SSPA?

+
+
+

Section 211 of the SSPA applies to an alien worker whose Social Security Number (SSN) + was first assigned on or after January 1, 2004. For the purposes of this provision + of the SSPA, an alien worker is a worker who is not a U.S. citizen or national of + the U.S. as defined in GN 00303.120.

+
+
+

NOTE: An alien worker whose SSN was assigned before January 1, 2004 is exempt from the + requirements of Section 211 of the Social Security Protection Act, even if the SSN + was not work authorized.

+
+
+

Although these provisions apply directly to certain alien workers, they can also affect + the entitlement of any person seeking a benefit on the record of an alien who is subject + to this law. For example, if an alien worker must be disallowed under Section 211 + of the SSPA, a child claiming benefits on that record would also be disallowed, regardless + of the child's citizenship or immigration status. See RS 00301.102F.6. for an example of an ESRD claim for a child who is affected by this provision.

+
+
+
+
+

2. Overview - what are the requirements of Section 211 of the SSPA?

+
+
+

Under Section 211 of the SSPA, an alien worker whose Social Security Number (SSN) + was originally assigned on or after January 1, 2004, must meet one of the following additional requirements to be fully or currently insured and to + establish entitlement to any Title II benefit or ESRD Medicare based on the alien + worker's earnings:

+
    +
  1. +
    +
    a. 
    +
    +

    The alien worker must have been issued an SSN for work purposes at any time on or + after January 1, 2004, see more information RS 00301.102.B.4.; OR

    +
    +
    +
  2. +
  3. +
    +
    b. 
    +
    +

    The alien worker must have been admitted to the U.S. at any time as a nonimmigrant + visitor for business (B-1) or as an alien crewman (D-1 or D-2), see more information + RS 00301.102B.5.

    +
    +
    +
  4. +
+

IMPORTANT: If an alien worker whose SSN was originally assigned 01/01/04 or later + does + not meet either of these additional requirements, then the worker is not fully or + currently insured. + This is true even if the alien worker appears to have the required number of QCs + in accordance with the regular insured status provisions found elsewhere in this subchapter. + Entitlement based on the alien worker's earnings is precluded. Disallow all claims + for benefits based on the alien worker's earnings in accordance with the procedure + in Step 18 in RS 00301.102D. or an example of a deceased alien worker who never had an SSN for work purposes or + admission as a B-1/D-1/D-2 nonimmigrant see RS 00301.102F.2. f.

+
+
+
+
+

3. SSN originally assigned on or after January 1, 2004

+
+
+
+
+

a. General

+
+
+

Section 211 of the SSPA applies for Title II and ESRD Medicare claims filed on the + account of an alien worker who was originally assigned an SSN on or after January + 1, 2004.

+

See how to determine when the SSN was originally assigned based on the NUMIDENT entries + see Steps 4 and 5 in RS 00301.102D.

+

See an example of when this law does not apply because the alien worker's SSN was + first assigned before 01/01/04 RS 00301.102F.3.

+
+
+
+
+

b. Special considerations for determining when an SSN was originally assigned

+
+
+

Additional development may be necessary to determine when an SSN was originally assigned + in the following unusual situations:

+
    +
  • +
    +
    •
    +
    +

    Wrong Number SS-5

    + +

    In a wrong number SS-5 case, SSA erroneously issued the alien worker an SSN with another + person's SSN instead of assigning the alien worker their own SSN (see RM 10220.350). + If an alien worker could have legitimately been assigned an SSN before 1/1/2004, the + worker is exempt from the requirements of section 211 of the SSPA.

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    Scrambled Earnings

    + +

    For the purpose of these instructions, a scrambled earnings case occurs when one person intentionally worked under another person's SSN, unlike the wrong number SS-5 scenario. In some + scrambled earnings cases, a person assumes the identity of the rightful NH, obtains + an SSN using documents showing the true NH's identity, and works under the true NH's + name and SSN (i.e., identity fraud is at issue). In other cases, a person works under + their own name but uses another person's SSN. Resolve scrambled earnings in accordance + with RM 03870.048 and MSOM EM 010.002 .

    + +

    For the purpose of determining whether an alien worker's SSN was originally assigned + on or after 1/1/2004, go by the SSN, if any, that was properly assigned to the alien worker based on their own true identity. Section 211 of the + SSPA applies if the alien worker's own SSN was assigned on or after 1/1/2004 or if + they have not yet been assigned an SSN based on their true identity.

    + +

    For an example of a case involving scrambled earnings see RS 00301.102F.4.

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    New SSN Assigned

    + +

    In certain situations, a worker who was originally and properly assigned one SSN may be assigned a new SSN in accordance with RM 10220.005, RM 10220.105, + or RM 10220.200 as appropriate.

    + +

    In this situation, the assignment of the original (i.e., the first) SSN rather than the new SSN is used to determine whether the alien + worker's SSN was originally assigned on or after 1/1/2004.

    + +

    If the alien worker's original SSN (i.e., the first SSN) was assigned on or after + 1/1/2004, then Section 211 of the SSPA applies.

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    SSN Applied for Before 1/1/2004, But SSN Date of Assignment Unclear

    + +

    For any case in which the alien worker applied for an SSN before 1/1/2004 but it is + unclear from the record whether the SSN was assigned 1/1/2004 or later, contact the + Regional Office for guidance.

    +
    +
    +
  • +
+
+
+
+
+
+
+

4. Alien worker was issued an SSN for work purposes on or after January 1, 2004

+
+
+
+
+

a. General rule

+
+
+

An alien worker who was properly issued a valid SSN for work purposes at any time on or after January 1, 2004 meets the work SSN requirement of the SSPA. The SSN for + work purposes can be issued in connection with the current claim. In general, SSA + issues an SSN for work purposes to an alien who has permission to work in the U.S. + from the Department of Homeland Security (DHS, formerly the Immigration and Naturalization + Service.)

+
+
+

NOTE: + If a special indicator on the NUMIDENT is present or may be applicable see RM 10215.200. + Contact your regional office for guidance.

+
+
+
+
+
+
+

b. Alien without work SSN is currently work authorized or had work authorization at time + of death

+
+
+

An alien worker who does not have an SSN card for work purposes is nevertheless considered + to meet the work SSN requirement of Section 211 of the SSPA if they meet one of the + following profiles:

+
    +
  • +
    +
    •
    +
    +

    Alien worker does not have an SSN, but is currently authorized to work in the U.S.; + or

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    Alien worker has/had an SSN, but not for work purposes (i.e., a nonwork SSN); and + is currently authorized to work in the U.S.; or

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    Deceased alien worker never had an SSN, but they had work authorization at the time + of death; or

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    Deceased alien worker had an SSN, but not for work purposes (i.e., a nonwork SSN); + and they had work authorization at the time of death.

    +
    +
    +
  • +
+

If an alien worker meets one of these profiles, take appropriate action to assign + an SSN to them and issue an SSN card for work purposes, as appropriate.

+

For adjudicating these claims under Section 211 of the SSPA see Steps 7-9 in RS 00301.102D.

+

For an example that illustrates this policy refer to the alternative scenario in RS 00301.102F.2.

+
+
+
+
+

c. Which covered earnings may be used to determine insured status?

+
+
+

If the alien was ever issued a valid SSN for work purposes on or after January 1, + 2004, then all of their covered earnings may be used to determine insured status, + regardless of the alien's current or prior immigration classification and/or work + authorization status.

+
+
+
+
+

d. Which insured status test(s) must be met?

+
+
+

Section 211 of the SSPA does not change which insured status test(s) apply. Therefore, insured status for an alien worker who has/had an SSN for work purposes + is determined based on the usual insured status test(s) described elsewhere in this + subchapter.

+

For example, a retired alien worker with an SSN for work purposes must still have + enough QCs to meet fully insured status.

+

For a chart of the applicable insured status test(s) for each type of benefit refer + to RS 00301.101B.

+
+
+

NOTE: It is possible that an alien worker who meets this work SSN card requirement under + Section 211 of the SSPA will not meet the applicable insured status test(s) according + to the rules found elsewhere in this subchapter. For processing an insured status + disallowance in this situation see Step 17 in RS 00301.102D.

+
+
+
+
+
+
+

e. Changes in the alien worker's immigration/work authorization status

+
+
+

The requirement for having an SSN for work purposes is met if the alien NH was properly + issued a work SSN card at any time on or after January 1, 2004, regardless of their + prior or current immigration/work authorization status.

+

The following table shows three common scenarios where the work SSN card requirement + is met:

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

If the alien worker...

+
+

And...

+
+
    +
  • +
    +
    •
    +
    +

    was previously issued a valid SSN card for work purposes,

    +
    +
    +
  • +
+ +

 

+
+

is not currently authorized to work in the United States.

+
+
    +
  • +
    +
    •
    +
    +

    was previously issued an SSN card for non-work purposes,

    +
    +
    +
  • +
+
+

is later issued an SSN card for work purposes.

+ +

 

+
+
    +
  • +
    +
    •
    +
    +

    began working without a valid SSN,

    +
    +
    +
  • +
+
+

is later assigned an SSN and issued a valid SSN card for work purposes.

+
+
+
+
+

NOTE: An alien worker does not meet the work SSN requirement if they have worked in the U.S. without authorization + from the U.S. immigration authority (i.e., illegally) using someone else's SSN, but + never had a valid SSN card for work purposes based on their own immigration documentation + and identity.

+
+
+
+
+
+
+

f. Where to find more information about work SSN issues

+
+
+
    +
  • +
    +
    •
    +
    +

    RS 00301.102D. Step 6 how to tell from the NUMIDENT record whether the alien NH was issued an SSN + card for work purposes on or after January 1, 2004

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    RS 00301.102F.1 An example of entitlement based on this provision

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    RS 00301.102F.4 An example involving entitlement of a work-authorized alien who had entered the U.S. + as an undocumented alien

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    RM 10201.055 SSN cards issued for work purposes

    +
    +
    +
  • +
+
+
+
+
+
+
+

5. Alien worker was admitted to the U.S. as a B-1, D-1, or D-2 nonimmigrant

+
+
+
+
+

a. General

+
+
+

A nonimmigrant is an alien who is admitted to the United States on a temporary basis. + To meet the B-1/D-1/D-2 nonimmigrant requirement of Section 211 of the SSPA, an alien + worker must have been admitted to the U.S. at any time in one of the following Department of Homeland Security (DHS) nonimmigrant categories:

+
    +
  • +
    +
    •
    +
    +

    B-1, a visitor for business; or

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    D-1, an alien crewman serving in a capacity required for normal operations on board + a vessel or aircraft, who departs from the United States with the vessel or aircraft + on which they arrived or another vessel or aircraft; or

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    D-2, an alien crewman serving in a capacity required for normal operations on board + a vessel or aircraft, who departs from Guam with the vessel on which they arrived.

    +
    +
    +
  • +
+

Alien crewmen (D-1 and D-2) are temporarily admitted to the U.S. for up to 29 days + at a time, with no extensions.

+
+
+
+
+

b. Which covered earnings may be used to determine insured status?

+
+
+

If the alien was ever admitted to the U.S. as a B-1, D-1, or D-2 nonimmigrant, then all of their covered earnings may be used to determine insured status, regardless of + the alien's current or prior immigration classification and/or work authorization + status.

+
+
+
+
+

c. Which insured status test must be met?

+
+
+

Section 211 of the SSPA does not change which insured status test(s) apply. Determine insured status using the applicable test(s) found elsewhere in this subchapter + for an alien worker who never had a SSN for work purposes but meets the requirement + for status as a B-1/D-1/D-2 nonimmigrant. For example, a D-1 worker disabled at age + 46 must still have enough QCs to meet fully insured status and 20/40. For a chart + of the applicable insured status test(s) for each type of benefit refer to RS 00301.101B.

+
+
+

NOTE: It is possible that an alien worker who meets the B-1/D-1/D-2 nonimmigrant requirement + under Section 211 of the SSPA will not meet the applicable insured status test(s) + according to the rules found elsewhere in this subchapter. For processing an insured + status disallowance in this situation see Step 17 in RS 00301.102D.

+
+
+
+
+
+
+

d. Where to find more information about insured status for B-1, D-1, and D-2 nonimmigrants

+
+
+
    +
  • +
    +
    •
    +
    +

    RS 00301.102D. Steps 10-14 for how to determine whether the alien worker has or had status as a + B-1, D-1 or D-2 nonimmigrant

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    RS 00301.102D. Step 16 d for a listing code when awarding benefits based on status as a B-1/D-1/D-2 + nonimmigrant

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    RS 00301.102D. Step 18 for disallowance processing if insured status based on having a work SSN + or B-1/D-1/D-2 nonimmigrant status is not met

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    RS 00301.102F.5 An example of a former D-1 alien worker who is entitled based on this provision

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    RS 00301.102D. and RS 00301.102F.7. Steps 11 and 12 for a special procedure to be used for B-1 truck drivers from Canada

    +
    +
    +
  • +
+
+
+
+
+
+
+ +
+
+

C. Policy interaction between section 211 of the SSPA and other provisions affecting + payment/entitlement of aliens

+
+
+
+
+

1. Lawful presence under welfare reform (RS 00204)

+
+
+
    +
  1. +
    +
    a. 
    +
    +

    Section 211 of P.L. 108-203 affects entitlement for the alien worker and any auxiliaries or survivors claiming Title II benefits + based on the alien worker's earnings.

    +
    +
    +
  2. +
  3. +
    +
    b. 
    +
    +

    The lawful presence requirements in RS 00204.000 affect whether an alien claimant (NH, auxiliary, or survivor) who is in the U.S. + and who has established entitlement to a Title II benefit can receive payment of that benefit.

    +
    +
    +
  4. +
+

These two provisions operate independently of each other. The following table presents + some of the possible scenarios involving the lawful presence provisions and Section 211 + of the SSPA:

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

If....

+
+

And...

+
+

Then...

+
+

An alien worker whose nonwork SSN was originally assigned on or after 1/1/04

+ +
    +
  • +
    +
    •
    +
    +

    never had an SSN card for work purposes; and

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    was never admitted to the U.S. based on the B-1, D-1, or D-2 nonimmigrant status,

    +
    +
    +
  • +
+ +

 

+
+

The alien worker is now lawfully present in the U.S. in accordance with RS 00204.025,

+
+

Disallow all claims for the alien worker and auxiliaries since the alien worker does + not meet either alternative insured status requirement of Section 211 of the SSPA.

+ +

For disallowance processing instructions see Step 18 in RS 00301.102D.

+
+

A deceased alien worker

+ +

was never assigned an SSN; and

+ +

was never authorized to work in the U.S or admitted to the U.S. as a B-1, D-1, or + D-2 nonimmigrant;

+
+

A survivor claimant is a lawfully present alien in accordance with RS 00204.025,

+
+

Disallow the survivor claim because the deceased alien worker did not meet either + alternative insured status requirement of Section 211 of the SSPA.

+ +

For disallowance processing instructions see Step 18 in RS 00301.102D.

+
+

An alien worker whose SSN was originally assigned on or after 1/1/04

+ +
    +
  • +
    +
    •
    +
    +

    was issued an SSN card for work purposes based on a temporary DHS work authorization; + and

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    has the required number of QCs for the type of benefit sought,

    +
    +
    +
  • +
+ +

 

+
+

The alien worker is currently in the U.S. but is not lawfully present in accordance + with RS 00204.025,

+
+

Award the claims for the alien worker and any auxiliaries since the alien worker meets + the work SSN requirement of Section 211 of the SSPA; but

+ +

Suspend the alien worker's benefits since they are not lawfully present in the U.S.

+ +

Any auxiliary claimants entitled on this NH's account would have to meet the lawful + presence or U.S. citizenship requirement in order to receive payment of benefits to + which they are entitled.

+
+
+
+
+
+
+

2. Alien nonpayment and removal provisions

+
+
+

The Social Security alien nonpayment and removal provisions operate independently + of Section 211 of the SSPA. Thus, an alien worker who is subject to and meets the + requirements of Section 211 of the SSPA may be entitled to benefits under Title II, but benefits must be suspended:

+
    +
  • +
    +
    •
    +
    +

    Under Section 202(t) of the Social Security Act if they have been outside the United + States for 6 calendar months and do not meet an exception to the alien nonpayment + provisions, RS 02610.000; or

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    Under Section 202(n) of the Social Security Act if they were removed from the United + States under certain sections of the Immigration and Nationality Act, RS 02635.000.

    +
    +
    +
  • +
+
+
+
+
+

3. Totalization agreements

+
+
+

U.S. totalization agreements do not override the additional requirements in section + 211 of the SSPA. Therefore, if:

+
    +
  • +
    +
    •
    +
    +

    The alien worker's SSN was originally assigned on or after 1/1/2004; and

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    They are a national of a totalization agreement country,

    +
    +
    +
  • +
+

then the alien worker must meet one of the additional insured status requirements + under Section 211 of the SSPA in order to be fully or currently insured and for anyone + to establish entitlement to any Title II benefits, including U.S. totalized benefits, + based on the alien worker's earnings.

+
+
+

NOTE: If the alien worker does not meet the requirements of Section 211 of the SSPA, the + other country which is party to a totalization agreement may use the worker's title + II coverage to determine eligibility for and amount of a benefit under the other country's + system.

+
+
+
+
+
+
+ +
+
+

D. Procedure development and determinations under section 211 of the SSPA

+
+
+

Use the step-action chart in this subsection to determine whether the alien worker + meets the requirements of Section 211 of the SSPA and whether an alien worker who + does not have an SSN can be assigned a number in connection with the current claim.

+

IMPORTANT: Verify the claimant's and the alien worker's identity in accordance with GN 00203.020 + before determining whether the worker meets the requirements of Section 211 of the + SSPA. (Establishing identity is required for all cases, not just cases involving Section + 211 of the SSPA.)

+
+
+

NOTE: For the purpose of this chart, the term claimant may refer to the worker or a person + claiming benefits as an auxiliary or survivor.

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Step

+
+

Action

+
+

1

+
+

Does the claimant allege that the worker is a U.S. citizen or national of the U.S.? + See GN 00303.120

+ +
    +
  • +
    +
    •
    +
    +

    If YES, continue with Step 2.

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    If NO, skip to Step 3.

    +
    +
    +
  • +
+
+

2

+
+

Has the claimant submitted acceptable evidence of the worker's U.S. citizenship/U.S. + nationality or does a prior SSA record establish the worker's U.S. citizenship/U.S. + nationality? See GN 00303.300

+ +
    +
  • +
    +
    •
    +
    +

    If YES, STOP. The provisions of Section 211 of the SSPA are not applicable since the worker is + not an alien. Determine insured status using all of the worker's covered earnings + and the regular instructions for insured status found elsewhere in this subchapter.

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    If NO, assume the worker is an alien and continue with Step 3.

    +
    +
    +
  • +
+
+

3

+
+

Does the alien worker have an SSN?

+ +
    +
  • +
    +
    •
    +
    +

    If YES, continue with Step 4.

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    If NO, skip to Step 7.

    +
    +
    +
  • +
+
+

4

+
+

Obtain the NUMIDENT record.

+ +

Is there a Special Indicator Code (SPIN) of 1, 2, 4, 5, or 7 on the NUMIDENT?

+ +
    +
  • +
    +
    •
    +
    +

    If YES, contact your Regional Office for guidance. See RM 10215.200. Continue with Step + 5.

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    If NO, continue with Step 5.

    +
    +
    +
  • +
+
+

5

+
+

Does the earliest NUMIDENT record for the alien worker's SSN (i.e., the record with an Entry Type Code + (ETC): O Original SSN show a Cycle Date (CYD) that is on or after 01/01/2004 indicating + that the SSN was originally assigned on or after 01/01/2004?

+ +
    +
  • +
    +
    •
    +
    +

    If YES, continue with Step 6.

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    If NO, STOP. The alien worker is exempt from the requirements of Section 211 of the SSPA. + Determine insured status using all of the worker's covered earnings and the regular + instructions for insured status found elsewhere in this subchapter.

    +
    +
    +
  • +
+ +
+
+

NOTE: There are 3 situations when the Cycle Date (CYD) on the earliest NUMIDENT record + may not be a reliable indicator of when the alien worker's SSN was originally assigned:

+
+
+ +
    +
  • +
    +
    •
    +
    +

    Wrong Number SS-5: can occur when SSA erroneously assigned another person's SSN to the alien worker (RM 10220.350). Obtain + a microprint of the SS-5 in accordance with RM 10220.350. If an alien worker could + have legitimately been assigned an SSN before 1/1/04, the worker is exempt from the + requirements of section 211 of the SSPA.

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    Scrambled earnings: can occur when one person intentionally uses another person's SSN (RM 03870.048 and MSOM EM 010.002 ). For the purpose of determining whether an alien worker's SSN + was originally assigned on or after 1/1/2004, go by the SSN, if any, that was properly assigned to the alien worker based on their own true identity. See RS 00301.102F.4. for an example of a case involving scrambled earnings.

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    New SSN: In certain situations, a worker who was originally and properly assigned one SSN + may be assigned a new (i.e., different) SSN in accordance with RM 10220.005, RM 10220.105, + or RM 10220.200 as appropriate. Use the date the original SSN was assigned to determine whether the alien worker's SSN was assigned on or after + 1/1/2004.

    +
    +
    +
  • +
+
+

6

+
+

For an alien worker who was originally assigned an SSN on or after 01/01/2004:

+ +

Does any record on the NUMIDENT for the alien's SSN (including the record established + for an SSN assigned in connection with the current claim) show one of the following + codes indicating the alien NH is or was at any time authorized to work in the United + States?

+ +
    +
  1. +
    +
    a. 
    +
    +

    An Evidence -Interview Code (IDN) of H indicating permanent employment authorization + as a lawful permanent resident (LAPR), refugee, asylee, or citizen of a Compact of + Free Association country, and thus has employment authorization inherent in immigration + status; or

    +
    +
    +
  2. +
  3. +
    +
    b. 
    +
    +

    An Evidence -Interview Code (IDN) of C and/or a Citizenship (CSP) of B indicating + status as a lawfully admitted alien with work authorization (but not an LAPR).

    +
    +
    +
  4. +
+ +

For Evidence - Interview Codes (IDN) , Citizenship (CSP) codes, and the Cycle Date + (CYD) field see RM 10235.005.

+ +
    +
  • +
    +
    •
    +
    +

    If YES, the alien worker meets the requirement for having a work SSN card under Section + 211 of the SSPA. Skip to Step 15 for determining whether the alien worker meets insured + status based on their covered earnings.

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    If NO, continue with Step 7.

    +
    +
    +
  • +
+ +
+
+

NOTE: Take action to correct erroneous Citizenship (CSP) or Evidence - Interview Codes + (IDN) before evaluating these codes under this step. If an erroneous code cannot be + corrected, evaluate the NUMIDENT record based on what the code should be and document + the folder accordingly.

+
+
+
+

7

+
+

For an alien worker who either has no SSN or has not been issued an SSN card for work + purposes (i.e., they have or had an SSN for nonwork purposes):

+ +

Does the claimant allege the alien worker currently has authorization to work in the + U.S., or, if the alien worker is deceased, does the claimant allege that the alien + worker had work authorization at the time of death?

+ +
    +
  • +
    +
    •
    +
    +

    If YES, continue with Step 8.

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    If NO, skip to Step 10.

    +
    +
    +
  • +
+
+

8

+
+

Verify current work authorization status or, if the alien worker is deceased, work + authorization at the time of death.

+ +
    +
  1. +
    +
    a. 
    +
    +

    Ask for documentary evidence of the alien worker's current authorization to work in + the U.S./work authorization at the time of death in accordance with RM 10211.420 and RM 10211.530.

    + +
    +
    +

    NOTE: Some alien categories, such as lawfully admitted permanent resident (LAPR), are automatically + work authorized. For example, an LAPR alien with an I-551 (Permanent Resident Card) + does not need a separate work permit document.

    +
    +
    +
    +
    +
  2. +
  3. +
    +
    b. 
    +
    +

    Click on the following link to the Administrative Confidential Memorandum ACM for evaluating these documents

    +
    +
    +
  4. +
  5. +
    +
    c. 
    +
    +

    If the claimant has submitted acceptable evidence of the alien worker's current work + authorization/work authorization at the time of death, obtain an online SAVE query + in accordance with RM 10214.110 and MSOM INTRANET 002.001 .

    +
    +
    +
  6. +
  7. +
    +
    d. 
    +
    +

    If the online SAVE query does not verify that the alien worker is currently authorized to work in the U.S. or that + they had work authorization at the time of death, request additional (secondary) verification + from DHS in accordance with RM 10214.150 and RM 10214.170.

    +
    +
    +
  8. +
+ +

The G-845 is available on SSA electronic forms or via the following DHS link: http://uscis.gov/graphics/formsfee/forms/g-845.htm

+ +
    +
  • +
    +
    •
    +
    +

    Enter the DHS office that services the SSAFO handling the claim for benefits. To find + the servicing DHS office see RM 10214.200.

    + +
    +
    +

    NOTE: The Office of International Operations should use the DHS office in Baltimore, Maryland + if the claimant is filing for benefits from outside the U.S.

    +
    +
    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    Attach to the G-845 legible photocopies of the alien worker's current DHS immigration/work + authorization document.

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    Establish a 30-calendar day diary to control for receipt of the G-845 response from + DHS.

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    Use the G-845 Supplement in SI 00502.115G as needed if verification of lawful presence is also required in accordance with + RS 00204.020.

    +
    +
    +
  • +
+ +

Continue with Step 9.

+
+

9

+
+

Upon receipt of DHS' reply to the online SAVE query/G-845 request for verification + of work authorization status from Step 8:

+ +

Does the alien worker have current authorization to work in the U.S., or, if deceased, + did they have work authorization at the time of death?

+ +
    +
  • +
    +
    •
    +
    +

    If YES, then the alien worker is considered to meet the work SSN requirement of Section + 211 of the SSPA. Skip to Step 15 for determining whether the alien worker meets insured + status based on their covered earnings.

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    If NO, continue with Step 10.

    +
    +
    +
  • +
+
+

10

+
+

Does the claimant allege that the alien worker was ever admitted to the U.S. as a + visitor for business (DHS code B-1) or as an alien crewman (DHS code D-1 or D-2)?

+ +
    +
  • +
    +
    •
    +
    +

    If YES, Continue with Step 11.

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    If NO, the alien worker does not meet the requirements of Section 211 of the SSPA. Skip + to Step 18 for processing a disallowance.

    +
    +
    +
  • +
+
+

11

+
+

Does the claimant allege that the alien worker has current or prior status as a B-1 + truck driver from Canada?

+ +
    +
  • +
    +
    •
    +
    +

    If YES, continue with Step 12.

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    If NO, skip to Step 13.

    +
    +
    +
  • +
+
+

12

+
+

Verify status as a B-1 truck driver from Canada:

+ +

DHS permits B-1 truck drivers from Canada to enter the U.S. without any immigration + documents. Therefore, do not use the G-845 process described in Step 13 to verify + status as B-1 (business visitor) for these workers. Instead, obtain the following + documentation:

+ +
    +
  • +
    +
    •
    +
    +

    Evidence of the alien worker's Canadian citizenship such as a Canadian birth certificate + see RM 10211.075; and

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    A written statement from the alien worker's employer indicating whether the alien + drove a truck in the U.S. for that company, and the applicable dates.

    +
    +
    +
  • +
+ +

The employer statement and evidence of Canadian citizenship will serve as evidence + of B-1 alien status for the purpose of Section 211 of the SSPA. for an example involving + a B-1 Canadian truck driver see RS 00301.102F.7.

+ +

CAUTION: This procedure only applies to B-1 truck drivers from Canada.

+ +

Skip to Step 14

+
+

13

+
+

Develop status as a B-1 (other than a Canadian truck driver), D-1, D-2 nonimmigrant + as follows:

+ +
    +
  1. +
    +
    a. 
    +
    +

    Ask for acceptable documentary evidence of the alien worker's current and/or prior + status as a B-1, D-1, or D-2 nonimmigrant. Acceptable evidence includes the following + documents:

    + +
      +
    • +
      +
      •
      +
      +

      DHS Form I-94 (Arrival Departure Record); or

      +
      +
      +
    • +
    • +
      +
      •
      +
      +

      DHS Form I-94 (Arrival Departure Record) in Unexpired Foreign Passport; or

      +
      +
      +
    • +
    • +
      +
      •
      +
      +

      I-95A&B or I-95 (Crewman's Landing Permit); or

      +
      +
      +
    • +
    • +
      +
      •
      +
      +

      I-184 (Alien Crewman Landing Permit and Identification Card);

      + +
      +
      +

      NOTE: DHS no longer issues the I-184, however an alien may have a valid card in their + possession that was previously issued by DHS; or

      +
      +
      +
      +
      +
    • +
    • +
      +
      •
      +
      +

      Other document as evidence of B-1, D-1, or D-2 nonimmigrant categories listed in RM + 10211.135 and RM 10211.530.

      +
      +
      +
    • +
    • +
      +
      •
      +
      +

      For evaluating these documents click on the following link to the Administrative Confidential + Memorandum ACM .

      + +
      +
      +

      NOTE: The alien may not have an immigration document as evidence of prior status as a B-1, D-1, or D-2 nonimmigrant. Also, a person with prior admission to + the U.S. as a B-1, D-1, or D-2 could file a claim for benefits at a Foreign Service + Post in their home country, rather than at a FO in the U.S. In this situation, the + alien worker would not have a current immigration document.

      +
      +
      +
      +
      +
    • +
    +
    +
    +
  2. +
  3. +
    +
    b. 
    +
    +

    If the claimant has submitted acceptable evidence of the alien worker's current status as a B-1, D-1, or D-2 nonimmigrant, obtain an online SAVE query in accordance + with RM 10214.110 and MSOM INTRANET 002.001 to verify the alien worker's current B-1, + D-1, or D-2 status. If the online SAVE query does not verify the alien worker's current B-1, D-1, or D-2 nonimmigrant status, get additional + (secondary) verification in accordance with d., of this step.

    +
    +
    +
  4. +
  5. +
    +
    c. 
    +
    +

    Ask the claimant to list all periods for which the alien worker may have been admitted + to the U.S. as a B-1, D-1, or D-2 nonimmigrant.

    +
    +
    +
  6. +
  7. +
    +
    d. 
    +
    +

    If the claimant alleges the alien worker has current and/or prior status as a B-1, + D-1, or D-2 nonimmigrant that is not verified via the online SAVE query, prepare a + G-845 (Document Verification Request) to request additional verification of alien + status from DHS as follows:

    + +
      +
    • +
      +
      •
      +
      +

      The G-845 is available on SSA electronic forms or via the following DHS link: https://www.uscis.gov/sites/default/files/document/forms/g-845.pdf

      +
      +
      +
    • +
    • +
      +
      •
      +
      +

      Enter the DHS office that services the SSAFO handling the claim for benefits. To find + the servicing DHS office see RM 10214.200.

      + +
      +
      +

      NOTE: The Office of International Operations should use the DHS office in Baltimore, Maryland + if the claimant is filing for benefits from outside the U.S.

      +
      +
      +
      +
      +
    • +
    • +
      +
      •
      +
      +

      In item 7 of Section A of the G-845, indicate the alleged nonimmigrant status (B-1, + D-1, or D-2) and all periods for which such status may be applicable. If necessary, + attach a separate sheet listing these periods with the alien worker's known identifying + data: name, DHS admission number (if known), date of birth, and address.

      +
      +
      +
    • +
    + +
      +
    • +
      +
      •
      +
      +

      IMPORTANT: Include a statement on the G-845 that it is only necessary for DHS to positively + verify (i.e. establish) one period of admission to the U.S. as a B-1, D-1, or D-2 nonimmigrant.

      +
      +
      +
    • +
    • +
      +
      •
      +
      +

      Attach to the G-845 legible photocopies of the alien's current DHS Form I-94 (Arrival/Departure + record) in an Unexpired Foreign Passport, I-95, I-184, or other immigration document + if available.

      +
      +
      +
    • +
    • +
      +
      •
      +
      +

      Establish a 30-calendar day diary to control for receipt of the G-845 response from + DHS.

      +
      +
      +
    • +
    • +
      +
      •
      +
      +

      Use the G-845 Supplement in SI 00502.115G as needed if verification of lawful presence is also required in accordance with + RS 00204.020.

      +
      +
      +
    • +
    + +

    Continue with Step 14.

    +
    +
    +
  8. +
+
+

14

+
+

Upon receipt of DHS' reply to the online SAVE query/G-845 verification request from + Step 13, or the B-1 documentation for a Canadian truck driver from Step 12:

+ +

Does the documentation/verification establish any one period of the alien worker's status as a B-1, D-1, or D-2 nonimmigrant?

+ +
    +
  • +
    +
    •
    +
    +

    If YES, the alien worker meets the requirements of Section 211 of the SSPA. Continue with + Step 15 for determining insured status.

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    If NO, the alien worker does not meet the requirements of Section 211 of the SSPA. Skip + to Step 18 for disallowance processing.

    +
    +
    +
  • +
+
+

15

+
+

Determine whether the alien worker meets the applicable insured status + test(s).

+ +

Determine insured status by using all of the alien worker's covered earnings and the + applicable insured status test(s) found elsewhere in this subchapter.

+ +

For which test(s) is applicable for each type of benefit see RS 00301.101B.

+ +

For the amounts needed for a QC for calendar years after 1977 see RS 00301.250.

+ +

Obtain acceptable evidence of earnings and resolve gaps in the earnings record and + all other earnings discrepancies in accordance with existing procedures.

+ +

Does the alien worker meet the applicable insured status test(s) for the type of benefit + being sought?

+ +
    +
  • +
    +
    •
    +
    +

    If YES, continue with Step 16 for processing an award, provided all other requirements for + entitlement are met.

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    If NO, skip to Step 17 for processing a regular insured status disallowance.

    +
    +
    +
  • +
+
+

16

+
+

Award: Alien worker meets the requirements of Section 211 of the SSPA and all other + requirements for insured status and benefit entitlement.

+ +

If a claimant seeking benefits based on the alien worker's earnings record (including + the alien worker) meets all of the requirements for entitlement, take the following + actions to process an award:

+ +
    +
  1. +
    +
    a. 
    +
    +

    If the alien worker has not yet been assigned an SSN, take action to assign an SSN + and if appropriate, issue an SSN card:

    + +
      +
    • +
      +
      •
      +
      +

      If the alien worker is currently a legal alien with work authorization, issue an SSN + card for work purposes in accordance with RM 10201.055, RM 10211.025, RM 10211.420, or RM 10211.530 as appropriate.

      +
      +
      +
    • +
    • +
      +
      •
      +
      +

      If the alien worker is currently a legal alien who is not authorized to work in the + U.S., issue an SSN card for nonwork purposes in accordance with RM 10211.600. (Applies only if the requirements of section 211 were met by reason of the alien + worker's status as a B-1, D-1, or D-1 nonimmigrant.)

      +
      +
      +
    • +
    • +
      +
      •
      +
      +

      If the alien worker is currently an undocumented alien, issue an SSN card for nonwork + purposes in accordance with RM 10211.500. (Applies only if the requirements of Section + 211 were met by reason of the alien worker's status as a B-1, D-1, or D-2 nonimmigrant.)

      +
      +
      +
    • +
    • +
      +
      •
      +
      +

      If the alien worker is deceased, follow RM 10225.080.

      +
      +
      +
    • +
    +
    +
    +
  2. +
  3. +
    +
    b. 
    +
    +

    Resolve all earnings discrepancies in accordance with established procedures. Use + the Item Correction Process (IC) to move wages from the suspense file or other records + to the alien worker's earnings record, as appropriate, see MSOM EM 010.002.

    +
    +
    +
  4. +
  5. +
    +
    c. 
    +
    +

    Process the Title II award through MCS/EC provided no other systems limitations apply.

    +
    +
    +
  6. +
  7. +
    +
    d. 
    +
    +

    If the alien worker is entitled based on admission to the U.S. as a B-1, D-1, or D-2 + nonimmigrant, list the case under code 291-- Section 211 SSPA Nonimmigrant B-1/D-1/D-2 award.

    +
    +
    +
  8. +
+
+

17

+
+

Regular insured status + disallowance-Alien + worker meets the requirements of Section 211 of the SSPA, but does not have enough + QCs to meet the + applicable insured status test(s).

+ +

Take the following actions to process a disallowance:

+ +
    +
  1. +
    +
    a. 
    +
    +

    Resolve all earnings discrepancies in accordance with existing procedures.

    +
    +
    +
  2. +
  3. +
    +
    b. 
    +
    +

    If the alien worker does not have an SSN for work purposes, but they are either:

    + +
      +
    • +
      +
      •
      +
      +

      Currently a legal alien with work authorization; or

      +
      +
      +
    • +
    • +
      +
      •
      +
      +

      Deceased, but they had work authorization at the time of death,

      +
      +
      +
    • +
    + +

    assign an SSN and issue an SSN card for work purposes in accordance with RM 10220.350, + RM 10211.025, RM 10211.420, RM 10211.530, or RM 10225.080 (deceased worker) as appropriate.

    +
    +
    +
  4. +
  5. +
    +
    c. 
    +
    +

    Process an insured status disallowance:

    + +
      +
    • +
      +
      •
      +
      +

      If the alien worker has an SSN, process the Title II insured status disallowance through + MCS/EC provided no other systems limitations apply. See GN 01010.440 for more information about insured status disallowances.

      +
      +
      +
    • +
    • +
      +
      •
      +
      +

      If the alien worker does not have an SSN, and one cannot be assigned in accordance + with RM 10211.600, RM 10211.500, RM 10225.080 (deceased worker), or RM 10211.530, process the case as an abandoned claim in accordance with GN 01010.420D.

      +
      +
      +
    • +
    +
    +
    +
  6. +
  7. +
    +
    d. 
    +
    +

    If necessary, add the appropriate insured status disallowance paragraphs to the notice. + See NL 00720.190 and RS 00301.102E.2. for MADCAP/manual insured status disallowance paragraphs.

    +
    +
    +
  8. +
+
+

18

+
+

Disallowance-Alien worker does not meet the requirements of Section 211 of the SSPA.

+ +

Take the following actions to process a disallowance:

+ +
    +
  1. +
    +
    a. 
    +
    +

    Resolve all earnings discrepancies in accordance with existing procedures.

    +
    +
    +
  2. +
  3. +
    +
    b. 
    +
    +

    Prepare a manual disallowance notice for the NH and any auxiliary/survivor claimants. + Include the paragraph in RS 00301.102E.1. in the notice.

    +
    +
    +
  4. +
  5. +
    +
    c. 
    +
    +

    If the alien worker has an SSN, take the following actions:

    + +
      +
    • +
      +
      •
      +
      +

      Exclude the case from MCS/EC processing.

      +
      +
      +
    • +
    • +
      +
      •
      +
      +

      Process a manual disallowance in accordance with GN 01010.440 through MADCAP/MACADE using the disallowance code 090 for DIB claims and 026 for + RSI claims. See SM 00805.400 for processing MADCAP disallowances.

      +
      +
      +
    • +
    • +
      +
      •
      +
      +

      List the case under code 292--Sec 211 SSPA Not Met.

      +
      +
      +
    • +
    +
    +
    +
  6. +
  7. +
    +
    d. 
    +
    +

    If the alien worker does not have an SSN, and one cannot be assigned in accordance + with RM 10211.600, RM 10211.500, or RM 10225.080 (deceased worker) take the following actions to disallow the claim:

    + +
      +
    • +
      +
      •
      +
      +

      Process the case as an abandoned claim in accordance with GN 01010.420D.

      +
      +
      +
    • +
    • +
      +
      •
      +
      +

      Email a copy of the disallowance notice and any alien status documentation to LP.PPDX.AES.Controls@ssa.gov. + Address the email cover sheet to:

      + +

      SSA-Program + Policy and Data Exchange

      + +

      Applications + and Electronic + Services

      + +

      + +

      Sec 211 SSPA Coordinator

      +
      +
      +
    • +
    +
    +
    +
  8. +
+
+
+
+
+ +
+
+

E. Procedure disallowance notices

+
+
+

To prepare a manual disallowance notice when the alien worker does not meet the requirements of Section + 211 of the SSPA follow in this section E.1.

+

To prepare a manual disallowance notice with the appropriate paragraph(s) follow in + this section E.2. when:

+
    +
  • +
    +
    •
    +
    +

    The alien worker meets the requirements of Section 211 of the SSPA; but

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    They do not meet the applicable insured status test(s) for the type of benefit being + sought; and

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    The disallowance cannot be processed via MCS/EC.

    +
    +
    +
  • +
+
+
+

1. Disallowance - alien worker does not meet requirements of SSPA 04

+
+
+

Use the Document Processing System (DPS) to prepare a manual disallowance notice when + the alien worker does not meet the requirements of Section 211 of the SSPA. Follow these steps:

+
    +
  1. +
    +
    a. 
    +
    +

    Under the Initial Claim menu select the template titled Disallowance - Title II misc. + reason.

    +
    +
    +
  2. +
  3. +
    +
    b. 
    +
    +

    Select the first optional paragraph titled Disallowed under Section 211 of the SSPA + of 2004 (DSL008).

    +
    +
    +
  4. +
  5. +
    +
    c. 
    +
    +

    Use the MADCAP disallowance paragraphs in the table below E.2. from NL 00720.190, as appropriate.

    +
    +
    +
  6. +
+
+
+
+
+

2. Disallowance alien worker does meet the requirements of SSPA 04 but is not insured + MCS/EC exclusion applies

+
+
+

Use DPS to prepare a manual notice when the alien worker does meet the requirements + of Section 211 of the SSPA but they do not meet the applicable insured status test(s) for the type of benefit being sought and + the disallowance cannot be processed via MC/EC.

+

Follow the steps:

+
    +
  1. +
    +
    a. 
    +
    +

    Under the Initial Claim menu select the template titled Disallowance - Title II misc. + reason.

    +
    +
    +
  2. +
  3. +
    +
    b. 
    +
    +

    Use the MADCAP disallowance paragraphs in the table below from NL 00720.190, as appropriate.

    +
    +
    +
  4. +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Paragraph Number

+
+

Title

+
+

Special Considerations

+
+

INS018 Q02

+
+

No benefits payable Not enough quarters earned

+
+

Use for the worker's or claimants notice.

+
+

INS008 Q05

+
+

No benefits payableNot enough quarters earned based on DOB

+
+

Use for the worker's or claimants notice.

+
+

INS018 (Q02)

+
+

No benefits payable Not enough quarters earned

+
+

Use for the workers or spouse's notice for life claim.

+
+

INS004 (Q14)

+
+

Survivor benefits not payable Deceased did not have enough quarters.

+
+

Use for survivor notice.

+ +

Deceased worker does not meet currently or fully insured status.

+
+

INS005 (Q15)

+
+

Benefits not payable- Did not work long enough under U.S. Social Security System

+
+

Use for the worker's or claimants notice.

+
+

INS007 (Q17)

+
+

Benefits Not Payable Not enough quarters to be fully or currently insured

+
+

Use for the survivors notice.

+
+

INS006 (Q18)

+
+

NH not insured for Medicare

+
+

Use for worker, spouse, or child filing for ESRD Medicare benefits.

+
+

INS017 (Q22)

+
+

Spouse or child claimant NH not insured for Medicare based on unproven DOB

+
+

Use for spouse or child filing for ESRD Medicare benefits.

+
+
+
+
+
+
+ +
+
+

F. Examples

+
+
+
+
+

1. Alien worker has prior but not current work authorization

+
+
+

Lucinda P. was first assigned their SSN and was issued an SSN card for work purposes + on 2/13/2004 based on temporary work authorization from DHS as an L-2 (nonimmigrant + spouse of an alien corporate executive). The temporary work authorization expired + on 2/12/2005. They file for RIB on 3/25/2005. At the time of filing for RIB, they + are a legal alien as an L-2 nonimmigrant, but do not have current authorization to + work in the U.S. Since Lucinda's SSN was first assigned on or after January 1, 2004, we must determine whether they meet + one of the requirements for entitlement under Section 211 of the SSPA.

+

SSPA: Since Lucinda was properly issued a valid SSN card for work purposes, they are exempt + from the prohibition on entitlement under Section 211 of the SSPA, even though they + are not currently authorized to work in the U.S. However, Lucinda must meet fully + insured status RS 00301.105, to be entitled to RIB. All of their covered earnings may be used to determine fully + insured status, regardless of their current immigration status or status at the time + they earned the QCs.

+

Lawful Presence: As an L-2 nonimmigrant, Lucinda is lawfully present in the U.S. Therefore, if they meet all of the requirements for entitlement to RIB, + they can receive payment of their benefit.

+
+
+
+
+

2. Deceased alien undocumented worker without SSN treatment of survivors

+
+
+

John W. entered the U.S. without being inspected by the immigration authorities (i.e., + they were an undocumented alien). They worked in the U.S. for 12 years without authorization + from the U.S. immigration authorities (DHS, formerly INS). They paid FICA taxes on + all of their earnings, which are covered earnings for Social Security purposes. John + W. died on 3/15/04. Their widow, who is lawfully residing in the U.S., and their minor + U.S. citizen children filed for survivor's benefits on 3/20/04. The deceased worker + was never assigned an SSN.

+

Prior to the enactment of the SSPA, the Social Security field office would have assigned + an SSN to John W. posthumously since the widow and minor surviving children appeared + eligible for survivor's benefits. That is, per RM 10225.080, SSA would have assigned an SSN to John W. as a deceased undocumented alien worker + because (1) the survivors would have been found eligible for a Federally funded benefit the Title II Social Security survivor's + benefits and (2), an SSN (for the worker) was a requirement for receiving that benefit.

+

However, under the SSPA, since John W. was never assigned an SSN when they were alive + and any posthumously assigned SSN would have to have been assigned on or after 01/01/2004, we must determine whether John W. met one of the + requirements under Section 211 of the SSPA:

+
    +
  • +
    +
    •
    +
    +

    Were they ever assigned an SSN and issued an SSN card for work purposes, RS 00301.102B.4. or Could they be assigned a work authorized SSN posthumously RM 10225.080?; or

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    Were they ever admitted to the U.S. as a B-1, D-1, or D-2 nonimmigrant RS 00301.102B.5.?

    +
    +
    +
  • +
+

In this case, John W. did not meet either requirement. Therefore, John W. does not + meet insured status because they did not meet one of the alternative insured status + requirements of Section 211 of the SSPA. This is true even though it appears that + they have enough QCs for currently or fully insured status. All entitlement based + on John W's earnings is precluded.

+

Since all entitlement based on John W’s earnings is precluded under Section 211 of + the SSPA, their survivors cannot be entitled on their record. SSA would not posthumously + assign an SSN to them merely to process the denial of benefits see RM 10225.080. Therefore, the alien worker's widow and the surviving children must be disallowed + using the abandoned claim procedures described in Step 18d of RS 00301.102D.

+

Alternative Scenario: If John W. had work authorization status at the time of their death, but had never + been assigned an SSN or issued an SSN card for work purposes, the insured status requirements + of section 211 of the Social Security Protection Act of 2004 would be met, see RS 00301.102B.4.b. In this case, determine whether or not they have enough QCs to meet insured status + in accordance with Step 15 in RS 00301.102D. If John W. had enough QCs to meet insured status, and all other requirements for + the survivors' entitlement were met, then we would assign an SSN to John W. posthumously + and process an award for the survivor claim in accordance with Step 16 in RS 00301.102D.

+
+
+
+
+

3. Undocumented alien worker whose SSN was assigned before 1/1/04, never had work SSN + or admission as nonimmigrant

+
+
+

Yelena entered the U.S. as a tourist on 4/13/93. Their tourist nonimmigrant status + expired 10/12/93; but they stayed on in the U.S. after that date without permission + from DHS. Thus, after 10/12/93, Yelena is in the U.S. as an undocumented alien. While + in the U.S., they had a daughter, Camille, who is a U.S. citizen by birth. Yelena + worked without authorization from the DHS (formerly INS) under Camille's SSN for 10 + years.

+

Yelena became disabled on 11/02/2003. They filed for DIB benefits for themselves and + child's benefits for Camille on 11/13/2003. Yelena can be entitled to DIB benefits + based on primary evidence of wages, resolution of the scrambled earnings, and evidence + that they met all factors of entitlement, including DIB insured status. Section 205(c)(2)(F) + of the Social Security Act requires a person to have an SSN as a condition for receipt + of Title II benefits. If no such number has been assigned, the claimant must apply + for an SSN.

+

SSA assigned an SSN for nonwork purposes to Yelena on 12/31/2003 in accordance with + RM 10211.500 since (1) they were found eligible for a Federally funded benefit (Title + II DIB) and (2) having an SSN is a requirement for receipt of that benefit. Since + Yelena is entitled to DIB, Camille can be entitled to child's benefits based on Yelena's + earnings record.

+

SSPA: Since Yelena's SSN was assigned before 01/01/2004, they do not have to meet one of + the insured status requirements in Section 211 of the SSPA (see RS 00301.102B.4. or RS 00301.102B.5.) in order to establish entitlement for themselves or Camille. See Step 5 in RS 00301.102D.

+

Lawful Presence: However, since Yelena is an alien who filed for benefits on or after 12/01/96, they + must meet the lawful presence requirement in RS 00204.010 and EM 98-002 dated 1/7/98 to receive payment of the DIB benefit to which they are + entitled. Since Yelena is not in any immigration status that is considered lawfully + present, their DIB benefits must be suspended effective with the first MOET. Camille's + benefits are not suspended since they are a U.S. citizen.

+
+
+
+
+

4. SSN assigned on or after 1/1/2004: alien NH has work SSN, prior status as undocumented + alien

+
+
+

Distaff entered the U.S. without inspection (i.e., they were an undocumented alien) + on 4/16/97. They worked without authorization from DHS for several years in covered + employment using their sibling's name and SSN. They applied for admission as a lawfully + admitted permanent resident alien (LAPR) and were granted LAPR status on 3/13/04. + Gustav applied for an SSN on 4/27/04 and was assigned an SSN and issued an SSN card + for work purposes on 5/12/04. They became disabled on 6/22/04. Gustav, their spouse + and children applied for Title II benefits on 6/30/04. The children are U.S. citizens; + the spouse is LAPR.

+

Gustav's own SSN was originally assigned on or after 1/1/04; therefore, we have to + determine whether they meet the requirements of Section 211 of the SSPA. Since Gustav + had been issued an SSN card for work purposes on 5/14/04, they meet the requirements + of Section 211 of the SSPA, see Step 6 in RS 00301.102D. Therefore, determine whether Gustav meets DIB insured status, RS 00301.120, using all of Their covered earnings, including wages and/or self-employment income + earned while they worked illegally under their sibling's SSN. Take the necessary corrective + action to move Gustav's earnings as an undocumented alien from their sibling's record + and/or the suspense file to the earnings record for their own SSN. For how to resolve + scrambled earnings see RM 03870.045. For documentation needed to transfer earnings from the incorrect record to the correct + record refer to RM 03816.016B. and RM 03870.048.

+

All of Gustav's covered earnings may be used to establish QCs and to determine insured + status. If Gustav meets the applicable insured status test(s), process an award in + accordance with Step 16 in RS 00301.102D. If they do not meet the insured status test(s), process an insured status disallowance + in accordance with Step 17 in RS 00301.102D.

+
+
+

NOTE: Gustav's spouse and children can be entitled if Gustav is entitled to benefits. Also, + Gustav and their spouse must meet the lawful presence requirement if they are in the + U.S., see RS 00204.010.

+
+
+
+
+
+
+

5. SSN assigned on or after 1/1/2004: alien NH never had work SSN, has prior status as + D-1 alien crewman

+
+
+

Kismet, a former D-1 alien, has worked as a flight attendant for Paradise Blue Airlines + for several years. They have never been assigned an SSN, nor were they ever issued + an SSN card for work purposes. They turned age 62 on 03/22/05 and filed for RIB. According + to Steps 10 and 13 c in RS 00301.102D, Kismet alleged that they have many prior periods of status as a D-1 alien crewman + nonimmigrant. They surrendered their most recent I-95A&B the last time they were in + the U.S., in November of 2004. Therefore, they have no current immigration document + that is indicative of D-1 status. Kismet listed their period of D-1 status in accordance + with Step 13 c in RS 00301.102D. as follows:

+
+ + + + + + + + + + + + + + + + + + + + + + + + +
+

Alleged periods of Kismet's admission
to the U.S. as a D-1 nonimmigrant

+
+

04/01/90-04/29/90

+ +

07/01/90-08/29/90

+ +

11/02/90-11/30/90

+ +

 

+ +

(no D-1 status in 1991)

+ +

 

+ +

02/01/92-03/01/92

+ +

05/01/92-05/01/92

+ +

08/02/92-08/30/92

+ +

 

+ +

02/02/93-03/01/03

+ +

06/03/93-07/01/93

+ +

12/02/93-12/30/93

+ +

 

+ +

05/01/94-05/29/94

+ +

06/01/94-06/29/94

+ +

08/02/94-08/30/94

+ +

 

+ +

(no D-1 status in 1995)

+ +

 

+ +

02/01/96-02/29/96

+ +

04/02/96-04/30/96

+ +

06/02/96-06/30/96

+
+

02/01/97-03/01/97

+ +

07/01/97-07/29/97

+ +

10/01/97-10/29/97

+ +

12/01/97-12/29/97

+ +

 

+ +

01/02/98-01/30/98

+ +

03/01/98-03/29/98

+ +

05/01/98-05/29/98

+ +

07/01/98-07/29/98

+ +

 

+ +

01/02/99-01/30/99

+ +

03/01/99-03/29/99

+ +

05/01/99-05/29/99

+ +

07/01/99-07/29/99

+ +

 

+ +

01/02/00-01/30/00

+ +

03/01/00-03/29/00

+ +

04/01/00-04/29/00

+ +

05/01/00-05/29/00

+ +

07/01/00-07/29/00

+ +

 

+ +

 

+
+

01/02/01-01/30/01

+ +

03/01/01-03/29/01

+ +

05/01/01-05/29/01

+ +

07/01/01-07/29/01

+ +

 

+ +

01/02/02-01/30/02

+ +

03/01/02-03/29/02

+ +

05/01/02-05/29/02

+ +

07/02/02-07/30/02

+ +

 

+ +

01/02/03-01/30/03

+ +

03/01/03-03/29/03

+ +

06/01/03-06/29/03

+ +

07/01/03-07/29/03

+ +

 

+ +

01/02/04-01/30/04

+ +

04/01/04-04/29/04

+ +

05/01/04-05/29/04

+ +

07/01/04-07/29/04

+ +

11/01/04-11/29/04

+ +

 

+
+
+

The adjudicator prepared a Form G-845 in accordance with Step 13d of RS 00301.102D requesting DHS to verify Kismet's status as a D-1 alien crewman and attached the + list of their alleged periods of status as D-1 nonimmigrant. The SSA adjudicator indicated + on the Form G-845 that positive DHS verification was needed for only one period of nonimmigrant status. DHS verified Kismet's most recent alleged period of + D-1 status (Step 14 in RS 00301.102D.). Therefore, Kismet meets the requirements of Section 211 of the SSPA.

+

The SSA adjudicator obtained the necessary evidence of Kismet's wages from their employers, + including Paradise Blue Airlines. (All of their earnings are in the suspense file + since they do not have an SSN). The adjudicator determines that Kismet meets fully + insured status based on all of their covered earnings (Step 15 of RS 00301.102D.). In addition, the adjudicator determined that they meet all of the other requirements + for entitlement to RIB.

+

Since Kismet can be entitled to benefits, SSA assigned them an SSN, issued an SSN + card for nonwork purposes, and awarded benefits in accordance with Step 16 in RS 00301.102D. In addition, the adjudicator moved Kismet's wages from the suspense file to the record + for their newly assigned SSN based on acceptable evidence of wages.

+
+
+
+
+

6. ESRD claim for U.S. citizen minor child: parent is undocumented alien, neither parent + has an SSN

+
+
+

Rocky and Oksana entered the U.S. in 1990 without inspection from the immigration + authorities (i.e., as undocumented aliens). Oksana never worked outside the home. + While in the U.S., Oksana gave birth to a child, Jessica. Since Jessica was born in + the U.S., they are a U.S. citizen by birth. Rocky and Oksana were never assigned SSNs. + Rocky worked steadily at many low paying jobs to support their family.

+

In February 2004, doctors diagnosed Jessica with ESRD. The hospital social worker + helped Rocky and Oksana file for ESRD Medicare benefits for Jessica. Under the existing + Medicare rules, a minor child can be entitled to Medicare for ESRD if the parent is fully or currently insured see HI 00801.201. The SSA adjudicator identified earnings in the suspense file for Rocky that would + normally give them more than 40 QCs.

+

To determine whether Jessica can get Medicare based on ESRD, the adjudicator must + determine whether their parent, Rocky, meets fully or currently insured status. To + do this, the adjudicator must first determine whether Rocky (an alien worker) is subject + to Section 211 of the SSPA. Refer to Step 5 in RS 00301.102D. Since Rocky did not have an SSN as of 01/01/2004, and any SSN that might eventually + be assigned to them would be assigned after 01/01/2004, Rocky is subject to Section 211 of the SSPA.

+

Next, the adjudicator must determine whether Rocky meets the requirements of Section + 211 of the SSPA in accordance with Steps 6 through 14 in RS 00301.102D. Since Rocky was never issued an SSN card for work purposes nor were they ever admitted + to the U.S. as a B-1/D-1/D-2 nonimmigrant, they do not meet the requirements of the + SSPA. Therefore, under Section 211 of the SSPA, Rocky does + not meet fully or currently insured status, even though they have enough covered earnings + that would + have given them more than 40 QCs. Because Rocky does not meet an insured status requirement under the Section 211 of + the SSPA, the ESRD claim for Jessica must be disallowed. Refer to Step 18, RS 00301.102D.

+
+
+

NOTE: Jessica's own citizenship or alien status does not affect whether they can be entitled + to ESRD Medicare benefits based on their parent's record.

+
+
+
+
+
+
+

7. Canadian B-1 commercial truck driver

+
+
+

Cyril Connolly drove a truck for Chansons Roulantes, Ltd., a Canadian music-box distribution company. They delivered hand-made music boxes + to WorldMart stores across the border in the U.S. once a week. Under DHS policy, commercial + truck drivers from Canada are allowed to enter the U.S. as B-1 visitors for business + without any immigration documentation. Therefore, Cyril was waived through inspection + at the border. They have no immigration documentation for their current or prior admissions + as a Canadian truck driver, nor were they ever assigned an SSN. Cyril's employer filed + W-2s reporting their U.S. covered employment (i.e., the work they performed while + driving the truck in the U.S.).

+

Cyril retired on 6/15/04 and is lawfully present in the U.S. Since Cyril has no SSN + as of January 1, 2004, They are automatically subject to Section 211 of the SSPA. + Also, since Cyril was never issued an SSN card for work purposes, the only way they + can be entitled to a Title II benefit is if they were ever admitted to the U.S. as + a B-1, D-1, or D-2 nonimmigrant and meets the applicable insured status test(s).

+

Because of the unique DHS policy of not issuing any immigration documents to B-1 Canadian + truck drivers, SSA must take a different approach to determine whether these workers + meet the requirements for insured status under Section 211 of the SSPA. Therefore, + in accordance with Steps 11 and 12 of RS 00301.102D., the adjudicator obtained a written statement from Cyril's former employer, Chansons Roulantes, Ltd., confirming that they drove a truck and made deliveries to U.S. customers and the + approximate dates of employment. (The adjudicator also obtained documentary evidence + of earnings at this time.) Cyril submitted their Canadian birth certificate to establish + that they are a Canadian citizen, see RM 10211.075. Their U.S. covered earnings are + in the suspense file since they have never been assigned an SSN.

+

Based on the written statement from the employer and evidence of Canadian citizenship, + establish B-1 nonimmigrant status for Cyril. Since they had been admitted to the U.S. + as a B-1, D-1, or D-2 nonimmigrant, Cyril meets the requirements of Section 211 of + the SSPA. Therefore, determine whether they meet insured status in accordance with + Step 15 of RS 00301.102D.

+

Under the usual insured status test, Cyril needs 40 QCs to meet fully insured status + for RIB.

+
    +
  • +
    +
    •
    +
    +

    If Cyril has enough QCs based on all of their covered earnings to meet fully insured + status for RIB and all other requirements for entitlement, assign them an SSN and + issued an SSN card for nonwork purposes in accordance with RM 10211.075 and RM 10211.600. Process an award in accordance with Step 16 in RS 00301.102.D.

    +
    +
    +
  • +
+
    +
  • +
    +
    •
    +
    +

    If Cyril does not have enough QCs using all of their covered earnings to meet fully + insured status for RIB, disallow the claim in accordance with Step 17 in RS 00301.102D. In this scenario, since Cyril is not entitled to a Federally funded benefit, they + cannot be assigned an SSN or issued a nonwork SSN card. Since they cannot be assigned + an SSN, use the abandoned claim procedure in Step 17c., second bullet, to process + the disallowance.

    +
    +
    +
  • +
+
+
+
+
+

8. Alien assigned nonwork SSN/issued nonwork SSN card before 1/1/2004

+
+
+

Catherine, age 18, entered the U.S. as a nonimmigrant on 02/14/00. They were a legal + alien not allowed to work. While in the U.S., Catherine applied for a driver's license + from the State of Pennsylvania on 04/03/00. At that time, the State of Pennsylvania + required a person to have an SSN in order to issue a driver's license. To meet the + State's requirement, they applied for an SSN on 04/05/00. SSA's enumeration procedures + in place at the time allowed for the assignment of an SSN and issuance of an SSN card + for nonwork purposes to an alien who applied for a driver's license from a State that + required an SSN for driver's licenses. In keeping with this policy, SSA assigned them + an SSN and issued them an SSN card for nonwork purposes on 6/12/00.

+
+
+

NOTE: SSA changed this policy on 10/27/2003: needing an SSN to obtain a driver's license + is no longer a valid reason for assigning an SSN/issuing an SSN card for nonwork purposes + see RM 10211.600

+
+
+

Even though they were not authorized to work in the U.S., Catherine began to work + in this country without DHS authorization. Their wages were covered for Social Security + purposes. Catherine's nonimmigrant status expired on 8/13/00. They remained in the + U.S. as an undocumented alien and continued to work without DHS authorization. On + 4/15/04, Catherine became disabled. They filed for DIB on 5/21/04.

+

SSPA and Insured Status: Since Catherine's SSN was first assigned before 1/1/2004, they are exempt from the + requirements of Section 211 of the SSPA (see Step 5 of RS 00301.102D). This is true even though they are an undocumented alien who are not allowed to + work in the U.S. Based on their covered earnings, Catherine met special insured status + for disabled workers under age 31.

+

Lawful Presence: Catherine's DIB benefits must be suspended since they are not lawfully present in + the U.S. see RS 00204.010.

+
+
+
+
+ +
+
+

G. References

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Topic

+
+

Reference

+
+

Legends on Social Security Card Relating to Work Authorization

+
+

RM 10201.055

+
+

Evidence codes (IDN) on the NUMIDENT

+
+

RM 10235.005

+
+

Evidence of Nonimmigrant Status for an SSN Card

+
+

RM 10211.135

+
+

Evidence for an SSN for a legal alien who is not allowed to work

+
+

RM 10211.600

+
+

Evidence for an SSN for an undocumented alien

+
+

RM 10211.500

+
+

List of Documents Establishing Lawful Alien Status for an SSN Card

+
+

RM 10211.530

+
+

Where to Mail Form G-845

+
+

RM 10214.200

+
+

Using the SAVE query

+
+

RM 10214.110

+
+

Wrong Number SS-5 Cases

+
+

RM 10220.350

+
+

Assigning SSN to deceased worker

+
+

RM 10225.080

+
+

Coding on the NUMIDENT

+
+

RM 10235.005

+
+

Scrambled Earnings

+
+

RM 03870.048

+
+

Evidence of Identity

+
+

GN 00203.020

+
+

Who is a Citizen or National of the U.S.

+
+

GN 00303.120

+
+

Evidence of U.S. citizenship

+
+

GN 00303.300

+
+

Disallowance for Abandoned Claim (i.e., worker has no SSN)

+
+

GN 01010.420

+
+

Insured Status disallowances

+
+

GN 01010.440

+
+

Overview of Totalization Benefits

+
+

GN 01701.100

+
+

Verification of lawful presence in the U.S.

+
+

RS 00204.020

+
+

Evidence of Lawful Presence in the United States

+
+

RS 00204.025

+
+

Insured StatusOverview

+
+

RS 00301.101

+
+

Fully Insured Status

+
+

RS 00301.105

+
+

Currently Insured Status

+
+

RS 00301.110

+
+

DIB Insured Status

+
+

RS 00301.120

+
+

Freeze Insured Status Requirements

+
+

RS 00301.130

+
+

Special Insured Status for Disability Before Age 31

+
+

RS 00301.140

+
+

Special Insured Status Requirements for Subsequent Periods of Disability - NH Over + Age 31

+
+

RS 00301.147

+
+

Date Last Insured (DLI)

+
+

RS 00301.148

+
+

Insured Status for Statutory Blindness

+
+

RS 00301.150

+
+

Amounts needed for a QC for years after 1977

+
+

RS 00301.250

+
+

Definition of Wages

+
+

RS 01401.005

+
+

Wage Evidence Policy

+
+

RS 01403.005

+
+

Primary Evidence of Wages

+
+

RS 01403.010

+
+

Statement of Employer as evidence of wages

+
+

RS 01403.013

+
+

How to request a Statement of Employer

+
+

RS 01403.035

+
+

Use of Form W-2/W-2C as Evidence of Pre-lag Wages

+
+

RS 01403.040A.3. and

+ +

RS 01404.175A.1.a

+
+

Secondary Evidence of Wages

+
+

RS 01403.050

+
+

Developing Gaps in the Earnings Record

+
+

RS 01404.003B.6.,

+ +

RS 01404.105B.2., and

+ +

RS 01404.120

+
+

Supplement to the G-845

+
+

SI 00502.115G.

+
+

Insured Status for Medicare

+
+

HI 00801.001A., HI 00801.006

+
+

Insured Status for Medicare based on ESRD

+
+

HI 00801.191C., HI 00801.201

+
+

Obtaining a DEQY

+
+

MSOM QUERIES 003.005

+
+

Obtaining a SAVE Query

+
+

MSOM INTRANET 002.001

+
+

Resolving earnings discrepancies through the Item Correction (IC) Process

+
+

MSOM EM 010.002

+
+
+
+
+
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301102
RS 00301.102 - Additional Requirements for Alien Workers- Social Security Protection Act of 2004 - 10/04/2023
+Batch run: 09/17/2026
+Rev:10/04/2023
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_105.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_105.html new file mode 100644 index 000000000..4e871e9b9 --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_105.html @@ -0,0 +1,504 @@ + + +SSA - POMS: RS 00301.105 - Fully Insured Status - 11/12/2010 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 48 (10-23)

+

RS 00301.105 Fully Insured Status

+ + +
+
+

CITATIONS:

+
+
+ +
42 USC 414(a), Social Security Act Sec. 214(a), 220,
+ +
20 CFR Sections 404.110, 404.115, 404.132, Section 211 of P.L. 108-203
+
+
+
+
+

A. Introduction

+
+
+
+
+

1. General

+
+
+

The fully insured status test is a “duration-of-work” test. This means that the number + holder (NH) must have worked for a certain length of time in order to meet insured + status. Fully insured status can also be thought of as a measure of the NH’s working + life. The fully insured status test is also called the “1-for-4” rule.

+
+
+
+
+

2. Two parts to fully insured status test

+
+
+

In general, there are two parts to the fully insured status determination:

+
    +
  1. +
    +
    a. 
    +
    +

    Determining the number of QCs needed (see RS 00301.105B of this section); and

    +
    +
    +
  2. +
  3. +
    +
    b. 
    +
    +

    Counting the QCs on the NH’s earnings record to see if they have enough to meet the + fully insured status requirement.

    +
    +
    +
  4. +
+

IMPORTANT: If the worker is an alien whose SSN was first assigned on or after January 1, 2004, + then they must meet additional requirements under Section 211 of the Social Security + Protection Act of 2004 (Public Law 108-203), to be fully insured and to establish + entitlement based on their earnings. See RS 00301.102 for a full discussion of these requirements.

+
+
+
+
+

3. Applicability of fully insured status test

+
+
+

Fully insured status applies to:

+
    +
  • +
    +
    •
    +
    +

    Monthly benefits payable 8/61 or later based on an application filed in or after 3/61; + or

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    Lump-sum death payments if the NH died on or after 8/1/61.

    +
    +
    +
  • +
+
+
+
+
+ +
+
+

B. Policy—number of QCS needed for fully insured status

+
+
+
+
+

1. Number of QCs under the 1-for-4 rule

+
+
+

A fully insured NH has at least one QC (whenever acquired) for each calendar year + after 1950 or after the year in which the person attained age 21, if later, up to + the year in which the NH attains age 62, or assumed age 62, or dies, whichever occurs + earlier. In determining the number of years, do not count any year if part or all + of that year is included in a period of disability if entitlement or a higher benefit + would result.

+
+
+
+
+

2. Additional considerations

+
+
+
    +
  1. +
    +
    a. 
    +
    +

    The QCs for fully insured status can be anywhere on the NH’s earnings record. The + NH meets fully insured status beginning with the first day of the most recent quarter + of coverage that is needed for fully insured status.

    +
    +
    +
  2. +
  3. +
    +
    b. 
    +
    +

    A NH needs at least 6 QCs and no more than 40 QCs to meet fully insured status.

    +
    +
    +
  4. +
  5. +
    +
    c. 
    +
    +

    A male NH born before 1/2/1911 is fully insured if he has one QC for each year after + 1950 up to the year he attains age 65 or dies, whichever is earlier. Men born from + 1/2/1911 through 1/1/1913 are fully insured if they have one QC for each year after + 1950 up to 1975, or the year of death, if earlier.

    +
    +
    +
  6. +
+
+
+
+
+ +
+
+

C. References

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TopicReference
+

Special Requirements for Alien Workers Under the Social Security Protection Act of + 2004

+
+

RS 00301.102

+
+

Fully Insured status for DIB

+
+

RS 00301.120B.2

+
+

Fully Insured status for a Freeze

+
+

RS 00301.130A.2

+
+

Fully insured status requirement for special insured status –NH under Age 31

+
+

RS 00301.140B.1.b

+
+

Fully insured status requirement for special insured status for subsequent period + of disability—NH Over Age 31

+
+

RS 00301.147B.2.a

+
+

Date Last Insured –fully insured status

+
+

RS 00301.148B.2.d

+
+

Fully insured status for Statutory Blind NH

+
+

RS 00301.150

+
+
+

 

+
+
+
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301105
RS 00301.105 - Fully Insured Status - 11/12/2010
+Batch run: 09/04/2026
+Rev:11/12/2010
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_106.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_106.html new file mode 100644 index 000000000..938a23bb1 --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_106.html @@ -0,0 +1,470 @@ + + +SSA - POMS: RS 00301.106 - Deemed Fully Insured - 10/06/2023 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 45 (10-23)

+

RS 00301.106 Deemed Fully Insured +

+ + +
+
+

A. Policy for deemed fully insured +

+
+
+
+
+

1. Applicability +

+
+
+

Any number holder (NH) who on 01/01/84 is:

+
    +
  • +
    +
    •
    +
    +

    age 55 or older; and

    + +
    +
    +
  • +
  • +
    +
    •
    +
    +

    an employee of a nonprofit (non-covered) employer which does not have in effect on + 01/01/84 a waiver certification (under section 312(k) of the Internal Revenue Code); + and +

    + +
    +
    +
  • +
  • +
    +
    •
    +
    +

    is extended coverage effective 01/01/84, solely because of the 1983 amendments, that + they can be deemed to be fully insured with fewer quarters of coverage (QC) than are + ordinarily required, if they are earned after 1983. +

    + +
    +
    +
  • +
+
+
+
+
+

2. Exceptions +

+
+
+

The deemed fully insured provision does not apply to a NH who declined coverage even + though a waiver certificate was in effect on 01/01/84. +

+

This provision does not apply to members of a religious order who have taken a vow-of-poverty.

+
+
+
+
+ +
+
+

B. Related policy for deemed fully insured +

+
+
+
+
+

1. Age and QC requirements for deemed fully insured status +

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

NH who, on 01/01/84 is:

+ +
+

The number of QCs required is:

+ +
+

Age 60 or over (date of birth (DB) on or before 01/02/24)

+ +
+

6

+ +
+

Age 59 or over but less than age 60 (DB 01/03/24 through 01/02/25)

+ +
+

8

+ +
+

Age 58 or over but less than age 59 (DB 01/03/25 through 01/02/26)

+ +
+

12

+ +
+

Age 57 or over but less than age 58 (DB 01/03/26 through 01/02/27

+ +
+

16

+ +
+

Age 55 or over but less than age 57 (DB 01/03/27 through 01/02/29)

+ +
+

20

+ +
+
+
+
+
+
+

2. Earliest effective month 01/01/84 +

+
+
+

A NH is deemed fully insured for all title II purposes if they meet the deemed fully + insured test. +

+

EXAMPLE: NH's coverage begins 01/01/84. The first month the NH meets deemed insured status + for Retirement Survivors Insurance benefits is 04/01/85. The first day of the first + month of a qualifying quarter. +

+
+
+
+
+

3. QCs earned before 01/01/84 +

+
+
+

Do not use QCs earned before 01/01/84 for deemed fully insured status. Use QCs earned + before 01/01/84 in addition to the QCs earned after 1983 to establish regular fully + insured status. +

+
+
+
+
+

4. NH works for different employer +

+
+
+

The only requirements for deemed fully insured status are the age and employment qualifications + as outlined in RS 00301.106A in this section. If a NH meets the requirements in RS 00301.106A in this section as of 01/01/84, and they take another position with a different employer + after 01/01/84 and earns additional QCs, use these QCs to establish deemed fully insured + status. +

+
+
+
+
+ + +
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301106
RS 00301.106 - Deemed Fully Insured - 10/06/2023
+Batch run: 10/06/2023
+Rev:10/06/2023
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_107.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_107.html new file mode 100644 index 000000000..18ea3296a --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_107.html @@ -0,0 +1,415 @@ + + +SSA - POMS: RS 00301.107 - Identification and Development of Deemed Fully Insured Status - 07/19/2002 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 20 (05-11)

+

RS 00301.107 Identification and Development of Deemed Fully Insured Status +

+ + +
+
+

A. Policy for identification and development of deemed fully insured status +

+
+
+

If a number holder (NH) does not have enough quarters of coverage to be fully insured + under the regular rules, determine whether the NH qualifies under the deemed fully + insured provision. Also, develop if the individual is fully insured but an earlier + month of entitlement (MOET) is possible under the deemed fully insured provision. +

+
+
+ +
+
+

B. Development for identification and development of deemed fully insured status +

+
+
+
+
+

1. Establishing employment status +

+
+
+

If the claimant submits a W-2 (Wage and Tax Statement) for 1983 or 1984 from the nonprofit + organization, accept the allegation that the NH was an employee as of 01/01/84. The + W-2 should meet the acceptability criteria in RS 01403.040. If necessary, contact the employer to resolve the matter. +

+
+
+
+
+

2. Sources +

+
+
+

Below are the sources for establishing employment status:

+
    +
  • +
    +
    •
    +
    +

    Earnings record;

    + +
    +
    +
  • +
  • +
    +
    •
    +
    +

    claimant;

    + +
    +
    +
  • +
  • +
    +
    •
    +
    +

    employer;

    + +
    +
    +
  • +
  • +
    +
    •
    +
    +

    primary and secondary evidence of wages (RS 01403.010 through RS 01403.077) and; +

    + +
    +
    +
  • +
  • +
    +
    •
    +
    +

    a precedent file.

    + +
    +
    +
  • +
+
+
+
+
+

3. When to contact employer +

+
+
+

Contact the employer to establish that deemed fully insured status does exist.

+

EXAMPLE: The employer will be in a position to know whether a waiver certificate was in effect + on 01/01/84, and whether the NH was an employee as of 01/01/84. +

+
+
+
+
+

4. When to use a precedent file +

+
+
+

To avoid needless contacts with employers, follow instructions in GN 01010.800. Use the precedent file to establish whether the claimant filed a waiver certificate + described in RS 00301.107B.5. in this section and document the claims file. +

+
+
+
+
+

5. Waiver certificate in effect +

+
+
+

A Form W-2 for 1983 from the nonprofit organization that shows that Federal Insurance + Contributions Act (FICA) tax was paid is sufficient documentation that the deemed + fully insured provision does not apply; assume that a waiver certificate was in effect + on 01/01/84. +

+
+
+
+
+

6. Treatment of church employees +

+
+
+

The 1983 Amendments included employees of a church or church-controlled organization + in the deemed fully insured provision. However, the Deficit Reduction Act of 1984 + gave these employers the option of having services performed by its employees excluded + from employment for SS purposes. These church employees are deemed self-employed and + cannot qualify under the deemed fully insured provision. For more information, see + RS 01802.234 and RS 01901.660. +

+
+
+
+
+

7. Earnings record (ER) requests if deemed fully insured status applies +

+
+
+

If deemed fully insured status applies after development, annotate ER request remarks: + “Apply Deemed Fully Insured Status.” For additional information on Deemed Fully Insured + Status, refer to RS 00301.106. The Office of Earnings Operations applies the provision in determining fully insured + status. +

+
+
+
+
+ + +
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301107
RS 00301.107 - Identification and Development of Deemed Fully Insured Status - 07/19/2002
+Batch run: 05/26/2011
+Rev:07/19/2002
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_110.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_110.html new file mode 100644 index 000000000..24172f03a --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_110.html @@ -0,0 +1,335 @@ + + +SSA - POMS: RS 00301.110 - Currently Insured Status - 08/18/2004 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 54 (10-23)

+

RS 00301.110 Currently Insured Status

+ + +
+
+

Policy

+
+
+
+
+

1. Individual currently insured

+
+
+

An individual is currently insured if they have at least six QC's during any one of + the following periods:

+
    +
  1. +
    +
    a. 
    +
    +

    The 13-quarter period ending with the quarter of death;

    +
    +
    +
  2. +
  3. +
    +
    b. 
    +
    +

    The 13-quarter period ending with the quarter in which they became entitled to a RIB; + or

    +
    +
    +
  4. +
  5. +
    +
    c. 
    +
    +

    The 13-quarter period ending with the quarter in which they most recently became entitled + to a DIB (e.g., disability onset date).

    +
    +
    +
  6. +
+

IMPORTANT: If the worker is an alien whose SSN was first assigned on or after January 1, 2004, + then they must meet additional requirements of Section 211 of the Social Security + Protection Act of 2004 (Public Law 108-203) to be currently insured and to establish + entitlement based on their earnings. See RS 00301.102 for a full discussion of these requirements.

+
+
+
+
+

2. Determining the 13 quarter period

+
+
+

In determining the 13-quarter period:

+
    +
  1. +
    +
    a. 
    +
    +

    Do not count as part of such 13-quarter period any quarter any part of which was included + in a period of disability except for the first and last quarters of the period of + disability if they are QCs.

    +
    +
    +
  2. +
  3. +
    +
    b. 
    +
    +

    An intervening period of disability may extend the 13-quarter period during which + the six QC's necessary for a currently insured status must be acquired.

    +
    +
    +
  4. +
+

 

+
+
+
+
+
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301110
RS 00301.110 - Currently Insured Status - 08/18/2004
+Batch run: 09/04/2026
+Rev:08/18/2004
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_120.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_120.html new file mode 100644 index 000000000..b098da97f --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_120.html @@ -0,0 +1,467 @@ + + +SSA - POMS: RS 00301.120 - DIB Insured Status - 08/18/2004 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 50 (10-23)

+

RS 00301.120 DIB Insured Status

+ + +
+
+

A. Introduction

+
+
+
+
+

1. NH Has DIB Insured Status

+
+
+

NH has DIB insured status if they:

+
    +
  1. +
    +
    a. 
    +
    +

    Have at least 20 QC's during a 40 quarter period ending with the quarter the waiting + period begins; and

    +
    +
    +
  2. +
  3. +
    +
    b. 
    +
    +

    Are fully insured in that quarter.

    +
    +
    +
  4. +
+

IMPORTANT: If the worker is an alien whose SSN was first assigned on or after January 1, 2004, + then they must meet additional requirements under Section 211 of the Social Security + Protection Act of 2004 (Public Law 108-203), to be insured and to establish entitlement + based on their earnings. See RS 00301.102 for a full discussion of these requirements.

+
+
+
+
+

2. Statutory Blindness - Insured Status

+
+
+

An individual disabled because of statutory -blindness may qualify for DIB freeze + or entitlement to DIB if they have fully insured status only. (See RS 00301.106 and RS 00301.150.)

+
+
+

NOTE: If the worker is an alien whose SSN was first assigned on or after January 1, 2004, + then they must meet additional requirements under Section 211 of the Social Security + Protection Act of 2004 to meet insured status. See RS 00301.102 for a full discussion of these requirements.

+
+
+
+
+
+
+

3. Meeting Tests - First Month of Waiting Period

+
+
+

In the first month of the waiting period:

+
    +
  • +
    +
    •
    +
    +

    An individual who becomes disabled when they had freeze insured status and remains + continuously disabled will continue to meet these tests in the first month of the + waiting period (even if it begins in a quarter after the quarter of onset).

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    An individual will have DIB insured status because the insured status met at onset + to establish the period of disability (i.e., a freeze) protects the insured status + the NH has at onset.

    +
    +
    +
  • +
+
+
+
+
+

4. No Waiting Period

+
+
+

If no waiting period is required for the current period of DIB because a period of + DIB entitlement or a disability freeze (no cash benefits) terminated within the past + 5 years, then the NH must have DIB insured status in the quarter of the first month + of entitlement for the current period of DIB.

+
+
+
+
+

5. Reference

+
+
+

For the special DIB insured status provision, an alternative to the 20/40 requirement, + see RS 00301.147.

+
+
+
+
+ +
+
+

B. Policy—Requirements for DIB Insured Status

+
+
+
+
+

1. 20/40 TEST

+
+
+
+
+

a. Period of Disability Considered

+
+
+

The NH will meet the 20/40 Test if:

+
    +
  • +
    +
    •
    +
    +

    The NH must have at least 20 QC's during a 40-quarter period ending with the quarter + in which the waiting period begins; or

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    If the NH does not have to serve a waiting period due to the termination of a prior + period of entitlement to DIB or freeze within the past five years, then they must + have 20/40 ending with the quarter of the first month of entitlement for the current + period of disability.

    +
    +
    +
  • +
+

In determining the 40-quarter period, do not count any quarter, all or part of which + is in a prior freeze or DIB period, except the beginning or ending quarter if they + are QC's.

+
+
+
+
+

b. Period of Disability Disregarded

+
+
+

If the NH's insured status is more advantageous without considering the period of + disability, the period may be disregarded. When there are two or more prior periods + of disability, either all must be disregarded or all must be used when determining + insured status and benefit amount. Non-creditable military wages or RR compensation + may not be used to establish QC's where the period of disability is disregarded even + though they may be used to establish a freeze.

+
+
+
+
+
+
+

2. Fully Insured Test

+
+
+

To meet the fully insured status test, the NH:

+
    +
  1. +
    +
    a. 
    +
    +

    Must have enough QC's to be fully insured in first month of waiting period; or

    +
    +
    +
  2. +
  3. +
    +
    b. 
    +
    +

    If the NH does not have to serve a waiting period due to the termination of a prior + period of DIB or freeze within the past five years, then they must be fully insured + in the quarter of the first month of entitlement for the current period.

    +
    +
    +
  4. +
+

 

+
+
+
+
+ +
+
+

C. Example

+
+
+

Guinness T. Lis became disabled on 12/15/77. As of that date, the NH was fully insured + and had 20 quarters of coverage in the 40-quarter period ending with the 12/77 quarter. + Although the NH remained continuously disabled and did not work after 12/77, they + did not file an application for DIB until 7/ 10 /88. Hence, the first month of the + waiting period is 2/87, the 17th month before the month of filing. Since the application + for DIB is also an application to establish a “freeze,” a period of disability may + be established beginning with 12/77. This enables the NH, who met the insured status + test at onset, to meet the test in 2/87, the first month of their waiting period.

+
+
+
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301120
RS 00301.120 - DIB Insured Status - 08/18/2004
+Batch run: 09/04/2026
+Rev:08/18/2004
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_122.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_122.html new file mode 100644 index 000000000..471831e27 --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_122.html @@ -0,0 +1,300 @@ + + +SSA - POMS: RS 00301.122 - Relationship Between Period of Disability and Insured Status - 01/23/2015 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 20 (05-11)

+

RS 00301.122 Relationship Between Period of Disability and Insured Status +

+ + +
+
+

A. Introduction to relationship between period of disability and insured status +

+
+
+

Establishing a period of disability reduces the number of quarters of coverage (QCs) + required for fully insured status and preserves currently insured status. However, + if including a period of disability results in a decrease or denial of benefits, disregard + the period of disability. +

+
+
+ +
+
+

B. Policy for relationship between period of disability and insured status +

+
+
+

If a freeze insured status is based on military service, wage credits, or railroad + (RR) compensation (that are not creditable as wages, described in RS 00301.131), the number holder (NH) may not be insured for cash benefit purposes. +

+

EXAMPLE: A period of disability established under a freeze reduces the QCs required for a + fully insured status from 14 to 8 but the NH has only 7 QCs from non-military covered + employment. Cash benefits are not payable. +

+
+
+ +
+
+

C. References +

+
+
+

RS 01601.260, Use of Earnings By RRB and SSA +

+
+
+ + +
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301122
RS 00301.122 - Relationship Between Period of Disability and Insured Status - 01/23/2015
+Batch run: 01/23/2015
+Rev:01/23/2015
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_130.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_130.html new file mode 100644 index 000000000..52e565e3a --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_130.html @@ -0,0 +1,364 @@ + + +SSA - POMS: RS 00301.130 - Freeze Insured Status Requirements - 08/18/2004 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 42 (10-23)

+

RS 00301.130 Freeze Insured Status Requirements

+ + +
+
+

Policy

+
+
+
+
+

1. What is Freeze Insured Status?

+
+
+

A NH has freeze insured status in a quarter if they:

+
    +
  1. +
    +
    a. 
    +
    +

    Have at least 20 QC's in a period of 40 consecutive calendar quarters ending with + that quarter; (see RS 00301.140 for alternative applicable to disability before age 31; see RS 00301.150 for statutory blindness exception); and

    +
    +
    +
  2. +
  3. +
    +
    b. 
    +
    +

    Are fully insured (see RS 00301.105).

    +
    +
    +
  4. +
+

IMPORTANT: If the worker is an alien whose SSN was first assigned on or after January 1, 2004, + then they must meet additional requirements under Section 211 of the Social Security + Protection Act of 2004 (Public Law 108-203), to be insured and to establish entitlement + based on their earnings. See RS 00301.102 for a full discussion of these requirements.

+
+
+
+
+

2. Retirement Age for Fully Insured Status

+
+
+
    +
  1. +
    +
    a. 
    +
    +

    Female's retirement age is 62.

    +
    +
    +
  2. +
  3. +
    +
    b. 
    +
    +

    Male's retirement age :

    + +
      +
    • +
      +
      •
      +
      +

      born 1/2/1913 or later is 62

      +
      +
      +
    • +
    + +
      +
    • +
      +
      •
      +
      +

      born 1/2/1911 to 1/1/1913 is deemed to have attained retirement age of 62 in 1975

      +
      +
      +
    • +
    + +
      +
    • +
      +
      •
      +
      +

      born 1/1/1911 or earlier - is age 65.

      +
      +
      +
    • +
    +
    +
    +
  4. +
+
+
+
+
+

3. Effect of DDS Determination On Freeze

+
+
+

A NH may have freeze insured status in the quarter of alleged onset of disability + but may not be insured in the quarter of onset established by the Disability Determination + Services (DDS). A freeze will not be established if insured status is last met in + any quarter before the quarter of disability established by the DDS.

+
+
+
+
+
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301130
RS 00301.130 - Freeze Insured Status Requirements - 08/18/2004
+Batch run: 09/04/2026
+Rev:08/18/2004
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_131.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_131.html new file mode 100644 index 000000000..cdc163469 --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_131.html @@ -0,0 +1,284 @@ + + +SSA - POMS: RS 00301.131 - Use of Railroad (RR) Compensation and Military Service (MS) Credits for Freeze Insured Status - 01/23/2015 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 20 (05-11)

+

RS 00301.131 Use of Railroad (RR) Compensation and Military Service (MS) Credits for Freeze Insured + Status +

+ + +
+
+

A. Policy for the use of RR compensation and MS credits for freeze insured status +

+
+
+

For freeze-insured status, include quarters of coverage based on certain RR compensation + or MS credits that are not creditable for other Retirement, Survivors, and Disability + Insurance purposes. +

+
+
+ +
+
+

B. References +

+
+
+

RS 01601.260, Use of Earnings By RRB and SSA +

+
+
+ + +
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301131
RS 00301.131 - Use of Railroad (RR) Compensation and Military Service (MS) Credits for Freeze Insured Status - 01/23/2015
+Batch run: 01/23/2015
+Rev:01/23/2015
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_132.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_132.html new file mode 100644 index 000000000..735e1639d --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_132.html @@ -0,0 +1,402 @@ + + +SSA - POMS: RS 00301.132 - Relationship Between Freeze Insured Status and Disability Insurance Benefits (DIB) Insured Status - 10/06/2023 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 44 (10-23)

+

RS 00301.132 Relationship Between Freeze Insured Status and Disability Insurance Benefits (DIB) + Insured Status +

+ + +
+
+

A. Introduction to relationship between freeze insured status and DIB insured status +

+
+
+

A number holder (NH) who is in freeze status or eligible for a freeze when they file + for DIB will usually have DIB insured status. However, the NH does not meet DIB insured + status if they meet the freeze insured status requirements only with the help of railroad + (RR) compensation or military service (MS) which is not creditable for monthly benefit + purposes. For Use of Earnings by RRB and SSA, see RS 01601.260 and for General Information on Crediting MS, see RS 01701.000. +

+

Conversely, where the NH does not have freeze insured status, they will not have DIB + insured status. +

+
+
+ +
+
+

B. Operating policy for relationship between freeze insured status and DIB insured status +

+
+
+
+
+

1. Effect of freeze +

+
+
+
    +
  • +
    +
    •
    +
    +

    Do not count as an elapsed year any year, part or all of which, is in a freeze period.

    + +
    +
    +
  • +
  • +
    +
    •
    +
    +

    You may count the first and last quarter of a period of disability, that meets the + definition of a quarter of coverage (QC). +

    + +
    +
    +
  • +
+
+
+
+
+

2. Effect of period of disability on QCs +

+
+
+

Do not count any quarter all or part of which is in a period of disability, except + the beginning or ending quarters if they are QCs, in determining the: +

+
    +
  • +
    +
    •
    +
    +

    40-quarter period;

    + +
    +
    +
  • +
  • +
    +
    •
    +
    +

    13-quarter period

    + +
    +
    +
  • +
  • +
    +
    •
    +
    +

    period for special insured status for disability before age 31 (see RS 00301.140); or +

    + +
    +
    +
  • +
  • +
    +
    •
    +
    +

    period of continuous QCs under the alternate insured status provision. (For additional + information, refer to RS 00301.480 Alternate Insured Status Test for NH’s Under a Disability Before 1956.) +

    + +
    +
    +
  • +
+
+
+
+
+ +
+
+

C. Related policy for relationship between freeze insured status and DIB insured status +

+
+
+
+
+

1. Denial or reduced benefits +

+
+
+

Do not use a freeze period if it would cause a denial of or reduced benefits. If there + are quarters within a period of disability that would be QCs but for the period of + disability, and entitlement is established based on these additional QCs, disregard + the freeze period and count the QCs. +

+
+
+
+
+

2. More than one DIB period +

+
+
+

When there are two or more prior periods of disability, either all must be disregarded + or all must be used for the current period of disability when computing insured status. +

+
+
+
+
+ + +
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301132
RS 00301.132 - Relationship Between Freeze Insured Status and Disability Insurance Benefits (DIB) Insured Status - 10/06/2023
+Batch run: 10/06/2023
+Rev:10/06/2023
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_140.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_140.html new file mode 100644 index 000000000..26083d8b1 --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_140.html @@ -0,0 +1,592 @@ + + +SSA - POMS: RS 00301.140 - Special Insured Status for Disability Before Age 31 - 04/15/2022 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 46 (10-23)

+

RS 00301.140 Special Insured Status for Disability Before Age 31

+ + +
+
+

A. Introduction

+
+
+

A special disability status provision allows an alternative to the 20/40 requirement + in RS 00301.120A and RS 00301.130.

+
+
+ +
+
+

B. Policy - Basic Rules for Special Insured Status

+
+
+
+
+

1. Requirements

+
+
+

For freeze applications filed in or after 1/68, and for monthly benefits beginning + February 1968 (based on applications filed in 1/68 or later), a NH has disability + insured status if they:

+
    +
  1. +
    +
    a. 
    +
    +

    Are under a disability which began before the quarter in which they attained or would + attain age 31; and

    +
    +
    +
  2. +
  3. +
    +
    b. 
    +
    +

    Are fully insured (see RS 00301.120B.2.); and

    +
    +
    +
  4. +
  5. +
    +
    c. 
    +
    +

    Have earned QC's in at least one-half of the calendar quarters during the period beginning + with the quarter after the quarter in which they attained age 21 and ending with the + quarter in which the period of disability began; or +

    +
    +
    +
  6. +
  7. +
    +
    d. 
    +
    +

    If the period contains less than 12 calendar quarters, the NH has earned 6 QC's in + the 12-quarter period ending with the quarter in which the period of disability began. + (When a period of disability begins in the quarter of attainment of age 24 or earlier, + the 6-QC rule will always apply.)

    +
    +
    +
  8. +
+
+ +
+

Note: Special insured status beneficiaries who continue to work may subsequently meet DIB + insured status (20/40 Test). In these scenarios, beneficiaries may become entitled + to the non-freeze computation effective with the quarter in which they meet DIB insured + status. For more information about the non-freeze computation, please see RS 00605.225.

+
+
+

IMPORTANT: If the worker is an alien whose SSN was first assigned on or after January 1, 2004, + then they must meet additional requirements under Section 211 of the Social Security + Protection Act of 2004 (Public Law 108-203), to be insured and to establish entitlement + based on their earnings. See RS 00301.102 for a full discussion of these requirements.

+
+
+
+
+

2. Born Before 1916

+
+
+
    +
  1. +
    +
    a. 
    +
    +

    A NH age 21 before 1937 must be fully insured and have earned QC's in half of the + quarters in the period beginning after 12/31/36 and ending with the quarter in which + the period of disability began.

    +
    +
    +
  2. +
  3. +
    +
    b. 
    +
    +

    The 6-QC minimum requirement also applies in cases where the period contains fewer + than 12 calendar quarters. (See RS 00301.149.)

    +
    +
    +
  4. +
+
+
+
+
+

3. QC's Must Be Earned in Correct Period

+
+
+
    +
  1. +
    +
    a. 
    +
    +

    The required quarters must be earned within the period after age 21 or in the 12-quarter + period described above, if that period is applicable.

    +
    +
    +
  2. +
  3. +
    +
    b. 
    +
    +

    If the number of elapsed quarters after age 21 is an odd number, subtract one elapsed + quarter from the total elapsed quarters.

    +
    +
    +
  4. +
+
+
+
+
+ +
+
+

C. Policy - Subsequent Period of Disability

+
+
+
    +
  1. +
    +
    1. 
    +
    +

    If there is a subsequent period of disability and NH is under age 31, see examples + 6-9 in RS 00301.140D.

    +
    +
    +
  2. +
  3. +
    +
    2. 
    +
    +

    If there is a subsequent period of disability and NH is age 31 or older at the time + of the new onset, see RS 00301.147

    +
    +
    +
  4. +
+

 

+
+
+ +
+
+

D. Examples

+
+
+
+
+

1. Disabled at Age 29

+
+
+

Fred Brown, born 5/13/58, became disabled 1/15/88 at age 29. To determine the number + of QC's necessary for insured status, count the quarters in the period which begins + with the quarter after the NH attains 21 and ends with the quarter in which they became + disabled. Since Fred Brown attained 21 in 5 /79 and became disabled on 1/15/88, the + period contains 35 calendar quarters. When the period contains an odd number of quarters, + one quarter is subtracted. In this case, the period then has 34 quarters for the purpose + of computing the QC requirement. Fred Brown must have earned 17 QC's (1/2 of 34) during + the period. The QC's must actually have been earned during this period; i.e., QC's + which Fred Brown had earned before 7/1/79 (the quarter after the attainment of age + 21) cannot be counted toward insured status.

+
+
+
+
+

2. Disabled at Age 22

+
+
+

Sam White, born 8/20/61, became disabled 4/12/84 at age 22. There are seven quarters + in the period after attainment of age 21 (8/82) and ending with the quarter of disability. + Since this period contains fewer than 12 quarters, Sam White must meet the alternative + “6-QC” requirement to be insured. They must have earned 6 QC's in the 12-quarter period + ending with the quarter of disability; i.e., 6 QC's in the 9/81 through 6/84 quarters. + A total of 6 QC's where some of which were earned before the 9/81 quarter, would not + give them insured status. However, they may have insured status at a later date.

+
+
+
+
+

3. Disabled Before Age 21

+
+
+

Mary Smith, born 11/15/64 became disabled 8/30/85 at age 20. Because the period of + disability occurred before 21, Mary must have 6 QC's in the 12-QTR period ending with + the QTR of onset. Mary's earnings record (ER) reflects the following QC pattern:

+

1982 NNNN      1983 NNNN

+

1984 CCCC      1985 CCNN

+

Counting back from the QTR of onset (9/85 quarter) 12 quarters, Mary requires 6 QC's + starting with the 12/82 quarter and ending with the 9/85 quarter. Mary has 6 QC's + in this 12 quarter period and meets insured status.

+
+
+
+
+

4. Required QC's Not in Correct Period

+
+
+

The same facts as Example 3 but with the following QC pattern:

+

1981 CCCC

+

1982 CNNN      1983 CNNN

+

1984 CCCN      1985 NNNN

+

Mary has 6 QC's, but not within a 12 quarter period ending with the quarter of onset. + Mary is not insured.

+
+
+
+
+

5. Moveable QC

+
+
+

The same facts as Example 3 but with the following QC pattern:

+

1982 CCCN      1983 NNNN

+

1984 CCCC      1985 CNNN

+

Since a QC earned after 1977 can be assigned to any QTR in the year if insured status + would be met (see RS 00301.230B.) the 9/82 QC will be allocated to the last QTR. Therefore, Mary has 6 QC's in the + 12-QTR period ending with the QTR of onset (9/85), and meets insured status.

+
+
+
+
+

6. Subsequent Period of DIB-NH Under Age 31

+
+
+

Joseph, DOB 9/16/56 became disabled 2/3/81. Their ER shows the following QC pattern:

+

1978 CCNN      1980   CCCC

+

1979 CCCN      1981   NNNN

+

Since Joseph became disabled after age 24, the 1-for-2 rule applies. There are 14 + QTRS elapsing after the QTR of age 21 up to and including onset date. Joseph requires + and has 7 QC's to be insured for DIB. Their period of disability ceased 10/82 and + terminated the last day of 12/82. Joseph became disabled again 2/14/84. Their ER now + shows the following QC pattern:

+

1977 NNNN      1981 CNNN

+

1978 CCNN      1982 CCNN

+

1979 CCCN      1983 CCCC

+

1980 CCCC      1984 CNNN

+

There are 18 QC's elapsing after age 21 up to and including onset (excluding the prior + period of disability (PPD). They require and have 9 QTRs to be insured for DIB as + of the new onset date.

+
+
+
+
+

7. Less Than 12 QC's After Age 21 - Subsequent Period of DIB

+
+
+

Jane born 3/16/67 became disabled 3/29/88 the quarter of attainment of age 21. Their + ER shows the following QC pattern:

+

1986 CCCN

+

1987 CCCN

+

1988 NNNN

+

Jane requires and has 6 QC's to be insured for DIB. Their period of disability ceased + 8/90 and terminated the last day of 10/90. They became disabled again 12/3/90. Their + ER remains the same. Since there are less than 12 QC's elapsing after the QTR of age + 21 up to the QTR of onset (the entire period being within a period of disability) + the qualifying period may be extended prior to age 21 and the QC's earned during that + period may be used. Jane has 6 QCs in the 12 -QTR period prior to age 21 and is insured + for DIB as of the new onset date.

+
+
+
+
+

8. Subsequent Period of DIB, Disabled Before 21

+
+
+

Ralph, born 4/12/67 became disabled 2/16/88, the QTR prior to age 21. Their ER shows + the following QC pattern:

+

1986 CNNN

+

1987 CCCC

+

1988 CNNN

+

Ralph requires and has 6 QC's to be insured for DIB. Their period of disability ceased + 10/90 and terminated the last day of 12/90. Ralph became disabled again 3/16/97. Their + ER shows the following QC pattern:

+

1986 CNNN      1992 NNNN

+

1987 CCCC       1993 CCNN

+

1988 CNNN      1994 CCCN

+

1989 NNNN      1995 CCCC

+

1990 NNNN      1996 CCCN

+

1991 NNNN      1997 NNNN

+

There are 25 QCs elapsing after the QTR of attainment of age 21 up to the QTR of onset, + excluding the prior period of disability (PPD). 25 being an odd number, it is reduced + by one to 24. Ralph requires and has 12 QC's to be insured as of the new onset date.

+
+
+
+
+

9. Subsequent Period of DIB, Not Insured for Subsequent Period

+
+
+

Sam, born 2/16/64, became disabled 12/16/85. Their ER shows the following QC pattern:

+

1983 CCNN

+

1984 CCCC

+

1985 NNNN

+

Sam requires and has 6 QC's to be insured for DIB. Their period of disability ceased + 10/89 and terminated the last day of 12/89.

+

They became disabled again 5/16/93. Their ER shows the following QC pattern:

+

1983 CCNN      1989 CCCC

+

1984 CCCC       1990 NNNN

+

1985 NNNN      1991 NNNN

+

1986 NNNN      1992 CCCC

+

1987 NNNN      1993 CCCC

+

1988 CCCC

+

There are 17 QC's elapsing after age 21 up to and including onset, excluding PPD. + The 12/89 QTR has been included because it is a QC and the ending QTR of the PPD (see + RS 00301.240). 17 being an odd number it is reduced to 16. Sam requires 8 QC's but has only 7 + QC's and does not meet insured status as of 5/93. They are, however, insured as of + the 12/93 quarter.

+
+
+
+
+
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301140
RS 00301.140 - Special Insured Status for Disability Before Age 31 - 04/15/2022
+Batch run: 09/04/2026
+Rev:04/15/2022
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_147.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_147.html new file mode 100644 index 000000000..ed32457b1 --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_147.html @@ -0,0 +1,1018 @@ + + +SSA - POMS: RS 00301.147 - Special Insured Status Requirements for Subsequent Periods of Disability - NH Over Age 31 - 04/21/2023 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 57 (10-23)

+

RS 00301.147 Special Insured Status Requirements for Subsequent Periods of Disability - NH Over + Age 31

+ + +
+
+

A. Background

+
+
+
+
+

1. Before 1983 Amendments

+
+
+

Before the 1983 Amendments, a disabled worker who became entitled to a period of disability + before age 31 under the special insured status requirements, and again became disabled + at or after age 31, had to meet the “20/40” and fully insured status requirements. + Many of these younger disabled NH's were denied since they had not worked long enough + to earn the required additional QC's.

+
+
+
+
+

2. 1983 Amendments

+
+
+

The 1983 Amendments relax the rules for establishing insured status for the young + disabled workers for subsequent periods of disability.

+
+
+
+
+ +
+
+

B. Policy—Basic Rules for Special Insured Status—NH Over Age 31

+
+
+
+
+

1. Applicability

+
+
+

The 1983 Amendments provisions apply only to disabled NH's who:

+
    +
  1. +
    +
    a. 
    +
    +

    Had a prior period of disability (PPD) established before age 31 and met only the + special insured status requirements; and

    +
    +
    +
  2. +
  3. +
    +
    b. 
    +
    +

    Do not currently meet 20/40 and fully insured status at onset.

    +
    +
    +
  4. +
+
+
+
+
+

2. Requirements For Special Insured Status

+
+
+
    +
  1. +
    +
    a. 
    +
    +

    Half of the quarters (QTR) after the QTR of age 21 up to and including the quarter + of onset are QC's up to a maximum of 20 QCs out of 40 calendar quarters; and

    +
    +
    +
  2. +
  3. +
    +
    b. 
    +
    +

    The person is fully insured.

    +
    +
    +
  4. +
  5. +
    +
    c. 
    +
    +

    If the total number of elapsed QTRs is an odd number, drop one. Do not count any QTRs + wholly or partially within a PPD except for the beginning and/or ending QTRs if they + are QCs.

    +
    +
    +
  6. +
  7. +
    +
    d. 
    +
    +

    If the number of elapsed QTRs is less than 12, the NH must have at least 6 QCs in + the 12-QTR period ending with the QTR of onset. The qualifying period may be extended + prior to age 21, and the QCs earned during that period may be used.

    +
    +
    +
  8. +
+

IMPORTANT: If the worker is an alien whose SSN was first assigned on or after January 1, 2004, + then they must meet additional requirements under Section 211 of the Social Security + Protection Act of 2004 (Public Law 108-203), to be insured and to establish entitlement + based on their earnings. See RS 00301.102 for a full discussion of these requirements.

+
+
+
+
+

3. Effective Date

+
+
+

Under the 1983 Amendments benefits may first be paid or recomputed beginning in 5/83. + However, the first possible month of entitlement may be earlier. These earlier months + may be counted as part of 24-month Medicare requirement.

+

NOTE: The earliest Medicare month of entitlement using these new rules is 5/83.

+
+
+
+
+ +
+
+

C. Examples

+
+
+
+
+

1. Special Insured Status-Met

+
+
+

Mary Brown, DOB 4/16/50, became disabled 5/16/75 at age 25. Their earnings record + (ER) showed the following work pattern:

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Earnings Record

+
+

 

+
+

1970 NNNC

+
+

1973 CNNC

+
+

1971 NNCC

+
+

1974 NNCC

+
+

1972 CCCN

+
+

1975 NNNN

+
+
+

Since there were 16 QTRs elapsing after the QTR of age 21 attainment (the 2nd QTR + of 1971) and up through their date of onset, Mary required 8 QCs to meet the special + insured status earnings test. Mary had 8 QC's during that period and was entitled + to a period of disability beginning 5/16/75. Their period of disability ceased 10/78 + and terminated the last day of 12/78; benefits terminated 1/79.

+

Mary filed for DIB again in 6/83, alleging an onset of 11/2/82 and prior filing on + their own SSN. An MBR establishes the dates of the PPD, and the ER shows the following:

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Earnings Record

+
+

 

+
+

1970 NNNC

+
+

1977 NNNN

+
+

1971 NNCC

+
+

1978 CCCC

+
+

1972 CCCN

+
+

1979 CNNN

+
+

1973 CNNC

+
+

1980 CNNN

+
+

1974 NNCC

+
+

1981 CNNN

+
+

1975 NNNN

+
+

1982 CCCN

+
+

1976 CNNN

+
+

1983 NNNN

+
+
+

There are 32 QTRs elapsing after the QTR of age 21 attainment up to and including + the alleged onset date (11/2/82). (Excluded from this elapsed period is the 2nd QTR + of 1975 through the 3rd QTR of 1978.) The last QTR of 1978 is a QC and is counted + as part of the elapsed period.

+

Mary requires and has 16 QC's during this elapsed period, and meets the special insured + status requirements for a second period of disability at onset.

+
+
+
+
+

2. Special Insured Status Met - Possible 20/40 Considered

+
+
+

John Jones, DB 7/16/40, became disabled 3/4/68, at age 28. Their ER shows the following + work pattern:

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Earnings Record

+
+

 

+
+

1961 NNNC

+
+

1965 NNNN

+
+

1962 NCCN

+
+

1966 CCNN

+
+

1963 NNCC

+
+

1967 CNCC

+
+

1964 CCNC

+
+

1968 NNNN

+
+
+

There are 26 QTRs elapsing after the QTR of age 21 attainment (the 3rd QTR of 1961) + and the QTR of disability onset, John required 13 QC's to meet the special insured + status earnings test. Since John had 13 QC's during this period, they were entitled + to a period of disability. John's disability ceased 04/15/81. Their benefits terminated + 7/81. Since no benefits were paid after 6/81, the period of disability ended on the + last day of 6/81 (the last payment month). This quarter is a QC, however, and must + be counted for any subsequent insured status.

+

John again files for DIB 6/83, alleging they became disabled 2/11/83. An MBR establishes + the dates of the prior period of disability, and their ER reflects the following:

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Earnings Record

+
+

 

+
+

 

+
+

1961 NNNC

+
+

1969 NNNN

+
+

1977 NNNC

+
+

1962 NCCN

+
+

1970 NNCC

+
+

1978 NNNN

+
+

1963 NNCC

+
+

1971 NNNN

+
+

1979 NNNN

+
+

1964 CCNC

+
+

1972 NNNN

+
+

1980 CCCC

+
+

1965 NNNN

+
+

1973 NNNN

+
+

1981 CCCC

+
+

1966 CCNN

+
+

1974 NNNN

+
+

1982 CCNN

+
+

1967 CNCC

+
+

1975 NNNN

+
+

1983 NNNN

+
+

1968 NNNN

+
+

1976 NNNN

+
+

 

+
+
+

There are 33 QTRs elapsing after the QTR of attainment of age 21 up to and including + the QTR of onset. We exclude from the elapsed period the 1st QTR of 1968 through the + first QTR of 1981. John requires and has 16 QC's to be entitled to a second period + of disability beginning 2/11/83. (If John had an additional 2 QC'S in any quarter + not part of the PPD, the provisions of the 1983 amendments would not apply since they + would meet the 20/40 and fully insured tests).

+
+
+
+
+

3. Requirements Not Met

+
+
+

Frank Smith, DB 7/14/45, became disabled 12/13/70, at age 25. Their ER shows the following + work pattern:

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Earnings Record

+
+

 

+
+

1966 NNNN

+
+

1969 NNNC

+
+

1967 CNCN

+
+

1970 CCCN

+
+

1968 NNCC

+
+

 

+
+
+

There were 17 QTRs elapsing after the QTR of attainment of age 21 up to and including + the QTR of onset, Frank required 8 QC's to be insured for DIB (since 17 is an odd + number, it was reduced to 16). Frank was entitled to a period of disability as of + 12/13/70. Their period of disability ceased 9/78 and terminated the last day of 11/78; + benefits terminated 12/78.

+

Frank files an SSA-16F6 on 6/14/83, alleging a new onset 2/11/83. Their ER now shows + the following:

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Earnings Record

+
+

 

+
+

 

+
+

1966 NNNN

+
+

1975 NNNN

+
+

 

+
+

1967 CNCN

+
+

1976 NCCN

+
+

 

+
+

1968 NNCC

+
+

1977 NNNN

+
+

 

+
+

1969 NNNC

+
+

1978 CNNN

+
+

 

+
+

1970 CCCN

+
+

1979 NNNN

+
+

 

+
+

1971 NNNN

+
+

1980 NNNN

+
+

 

+
+

1972 NNNN

+
+

1981 NNNN

+
+

 

+
+

1973 NNNN

+
+

1982 NNNN

+
+

 

+
+

1974 NNNN

+
+

1983 NNNN

+
+

 

+
+
+

There are 33 QTRs elapsing after the QTR of attainment of age 21 up to and including + the QTR of onset (excluding the prior period of disability). Since this is an odd + number, it is reduced to 32. Frank requires 16 QC's to meet insured status for a new + period of disability but has only 8 QC's. Their claim must be denied.

+
+
+
+
+
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301147
RS 00301.147 - Special Insured Status Requirements for Subsequent Periods of Disability - NH Over Age 31 - 04/21/2023
+Batch run: 09/04/2026
+Rev:04/21/2023
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_148.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_148.html new file mode 100644 index 000000000..7a62d66ba --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_148.html @@ -0,0 +1,501 @@ + + +SSA - POMS: RS 00301.148 - Date Last Insured (DLI) - 01/13/2006 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 49 (10-23)

+

RS 00301.148 Date Last Insured (DLI)

+ + +
+
+

A. Introduction

+
+
+

DLI is the last day in the last quarter when disability insured status is met. (See + RS 00301.120 for an explanation of disability insured status.) As of the DLI the individual must + be fully insured or deemed fully insured, and must meet the appropriate disability + insured test.

+
+
+

NOTE: DLI for individuals who are disabled due to statutory blindness is figured based + on fully insured status alone. See RS 00301.150.

+
+
+
+
+ +
+
+

B. Policy - Rules For Determining DLI

+
+
+
+
+

1. When Determined

+
+
+

In certain disability cases when the disability is not caused by a traumatic event, + the DDS must provide an onset date based on medical evidence. As part of their determination, + they may require the DLI. This will usually be furnished on the earnings record. However, + changes to the date known to the system (such as a different prior period of disability + or variance in quarters of coverage previously posted to the record) may require a + manual calculation of DLI.

+
+
+
+
+

2. How To Determine DLI

+
+
+
    +
  1. +
    +
    a. 
    +
    +

    Determine the date 20/40 is last met.

    +
    +
    +
  2. +
  3. +
    +
    b. 
    +
    +

    If 20/40 is not met and either the NH is under age 31 or special insured status previously + applied, determine date NH last meets special insured status.

    + +

    Special age 31 status does not need to be tested, if the NH is age 31 or older at + onset and special insured status was not previously applied. The 20/40 test will always + be used.

    +
    +
    +
  4. +
  5. +
    +
    c. 
    +
    +

    Choose the later of the date in RS 00301.148B.2.a. or RS 00301.148B.2.b.

    +
    +
    +
  6. +
  7. +
    +
    d. 
    +
    +

    Determine if fully insured status is met as of the date chosen in c. above. If fully + insured status is also met, this is DLI. If not, redetermine 20/40 and special insured + status for the fourth quarter of the prior year. Repeat this process until the NH + has met both the DIB insured status and the fully insured status tests.

    +
    +
    +
  8. +
  9. +
    +
    e. 
    +
    +

    If full retirement age (FRA) attainment is involved, the DLI is the last day of the + quarter before the quarter of FRA attainment. For example, if FRA attainment is 11/2019, + the DLI is 9/30/2019.

    +
    +
    +
  10. +
+
+
+

NOTE: DLI for individuals disabled due to statutory blindness is the date fully insured + status is last met. The 20-40 insured status test does not apply. See RS 00301.150.

+
+
+

IMPORTANT: If the worker is an alien whose SSN was first assigned on or after January 1, 2004, + then they must meet additional requirements under Section 211 of the Social Security + Protection Act of 2004 (Public Law 108-203), to be insured and to establish entitlement + based on their earnings. See RS 00301.102 for a full discussion of these requirements.

+
+
+
+
+ +
+
+

C. Example

+
+
+

The NH's DOB is 3/09/54 and the earnings record is as follows:

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

1973 CCNN

+
+

1981 CCNN

+
+

1989 NNNN

+
+

1974 NNNN

+
+

1982 CCCC

+
+

1990 NNNN

+
+

1975 CCCC

+
+

1983 NNNN

+
+

1991

+
+

1976 CCCC

+
+

1984 NNNN

+
+

1992

+
+

1977 NNNN

+
+

1985 CCCC

+
+

1993

+
+

1978 NNNN

+
+

1986 CCCC

+
+

1994

+
+

1979 NNNN

+
+

1987 CCNN

+
+

1995

+
+

1980 CCNN

+
+

1988 CCNN

+
+

1996

+
+
+

The NH last meets 20/40 insured as of 6/30/90. The 3/80 and 6/80 QC's were based on + annual postings so it is permissible to move them to the 9 /80 and 12/80 quarter. + As of 1990, this NH needs 14 QC's to be fully insured. They have 30 QC's so DLI is + 6/30/90.

+
+
+
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301148
RS 00301.148 - Date Last Insured (DLI) - 01/13/2006
+Batch run: 09/04/2026
+Rev:01/13/2006
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_149.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_149.html new file mode 100644 index 000000000..89abea29b --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_149.html @@ -0,0 +1,263 @@ + + +SSA - POMS: RS 00301.149 - SSA-1164 Exhibit of Special Insured Status Worksheet - 06/23/2011 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 20 (05-11)

+

RS 00301.149 SSA-1164 Exhibit of Special Insured Status Worksheet +

+ + +

SSA-1164 Worksheet Special Insured Status (Front) - Exhibit

+ +

See OS 15020.220 for SSA-1164, Worksheet – Special Insured Status

+ + +
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301149
RS 00301.149 - SSA-1164 Exhibit of Special Insured Status Worksheet - 06/23/2011
+Batch run: 06/23/2011
+Rev:06/23/2011
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_150.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_150.html new file mode 100644 index 000000000..29825afa9 --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_150.html @@ -0,0 +1,405 @@ + + +SSA - POMS: RS 00301.150 - Insured Status for Statutory Blindness - 10/12/2023 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 63 (04-26)

+

RS 00301.150 Insured Status for Statutory Blindness

+ + +
+
+

A. Background

+
+
+

An NH disabled by reason of statutory blindness as defined in section 216(i)(1)(B) + of the Act (see DI 10105.065, DI 10501.001 + and DI 24001.010) may qualify for a disability freeze or entitlement to DIB if they have fully insured + status in the quarter they become disabled, or on the first day of the first quarter + thereafter in which they have fully insured status. For benefits payable January 1973 + or later, a statutorily blind worker no longer needs to meet a 20/40 or special insured + status test. This provision applies regardless of the age at which the individual + is disabled. See DI 11005.045C.1. for instructions on completing the EDCS 3367 or SSA-3367 when a claimant has insured + status for statutory blindness. Properly following these instructions will alert the + DDS to the presence of a second date last insured, which may be material to establishing + the onset date.

+

IMPORTANT: If the worker is an alien whose SSN was first assigned on or after January 1, 2004, + then they must meet additional requirements under Section 211 of the Social Security + Protection Act of 2004 (Public Law 108-203), to be fully insured and to establish + entitlement based on their earnings. See RS 00301.102 for a full discussion of these requirements.

+
+
+ +
+
+

B. Policy - insured status for statutorily blind workers

+
+
+
+
+

1. Requirements

+
+
+

At least one quarter of coverage for each year after 1950 (or, if later, the year + in which they attained age 21) up to the year in which the qualifying QC is earned.

+
+
+
+
+

2. Minimum

+
+
+

There is a minimum requirement of six QC's.

+
+
+
+
+

3. Insured status not met at onset

+
+
+

Where the period of disability does not begin with the quarter of onset, because insured + status is not met, it will begin with the first quarter thereafter in which fully + insured status exists, provided the NH is disabled in that quarter.

+
+
+
+
+ +
+
+

C. Example

+
+
+

Calvin Hill, DOB 7/12/57, is statutorily blind from birth. They first secure employment + through Vocational Rehabilitation in the 09/77 quarter and have sporadic work attempts + there after. Their period of disability would begin with the 06/86 quarter (with a + date first insured of 04/01/1986), the first point at which they are both fully insured + and under a disability.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

1977 NNCC

+
+

1983 CNNN

+
+

1978 NNNN

+
+

1984 NNNN

+
+

1979 NNNN

+
+

1985 CNNN

+
+

1980 NNNN

+
+

1986 CCNN

+
+

1981 NNNN

+
+

1987 CCCC

+
+

1982 CNNN

+
+

 

+
+
+

Although Calvin Hill's onset is at birth and they acquire their sixth QC in the 03/86 + quarter, the period of disability cannot begin at that point since they would require + seven QCs to be fully insured as of that quarter; i.e., there are 7 years elapsing + between 1978, the year they attained age 21, and 1986, the year in which they have + their qualifying QC for fully insured status. Their period of disability would begin + with the 06/86 quarter the first point at which they are both fully insured and under + a disability.

+
+
+
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301150
RS 00301.150 - Insured Status for Statutory Blindness - 10/12/2023
+Batch run: 09/22/2026
+Rev:10/12/2023
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_160.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_160.html new file mode 100644 index 000000000..80a7987a3 --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_160.html @@ -0,0 +1,440 @@ + + +SSA - POMS: RS 00301.160 - Insured Status Based on Medicare Qualified Government Employment - 05/26/2011 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 53 (10-23)

+

RS 00301.160 Insured Status Based on Medicare Qualified Government Employment

+ + +
+
+

A. Policy for federal employment

+
+
+

Federal employees pay taxes on all wages (subject to the limitations in RS 01401.030) after 12/31/82 for Medicare purposes. Credit these Government Employment Quarters + of Coverage's (GEQC) in the same ways as regular QCs.

+

Federal employees in an employee or employer, relationship with a Federal Agency at + any time during 01/83 and before 02/83 will receive deemed government QCs (DQCs) for + federal service before 01/83.

+

Use GEQCs, DQCs, and regular QCs to establish the insured status requirements for + Medicare purposes. If the Federal employee is insured using only regular QCs, no further + development is required.

+
+
+ +
+
+

B. Policy for deemed QCs (DQC)

+
+
+
+
+

1. Prior to 1978

+
+
+

The rules for establishing DCQs for Federal employees are in HI 00801.430.

+
+
+
+
+

2. After 1977

+
+
+

To determine DQCs, refer to the increment amounts chart in RS 00301.250. Assume the wages were subject to Federal Insurance Contribution Act (FICA). Establish + no more than four DQCs for any year.

+

Since the insured status requirements for Medicare government employees are the same + as for title II benefits, a prior period of disability in which title II benefits + were payable or a “freeze” established can reduce the number of QCs needed for Medicare + purposes.

+

See also:

+
    +
  • +
    +
    •
    +
    +

    RS 00301.105, Fully Insured Status

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    RS 00301.122, Relationship Between Period of Disability and Insured Status, see

    +
    +
    +
  • +
  • +
    +
    •
    +
    +

    RS 00301.132, Relationship Between Freeze Insured Status and DIB Insured Status).

    +
    +
    +
  • +
+

If you cannot consider any of the Federal employment wages for SS coverage purposes, + do not grant FQCs or DFQCs for this service for Medicare purposes.

+
+
+
+
+ +
+
+

C. Policy for state and local employment

+
+
+

Public Law 99-272 extended mandatory coverage for Medicare to certain State and local + workers. State and local employees who are not otherwise covered under a voluntary + Social Security agreement and employees hired after 03/31/ 86 earn GEQCs for Medicare + purposes.

+

Employees hired before 04/01/86 who are not subject to a coverage agreement may be + covered if the State or local employer elects this coverage by modifying the voluntary + agreement. However, unlike Federal employees, there is no provision for deemed QCs + for any employment prior to 04/01/86.

+

Credit GEQCs the same way as regular QCs. You may combine GEQCs and regular QCs to + quality for Medicare.

+
+
+ +
+
+

D. Policy for the types of Medicare insured status

+
+
+
+
+

1. General

+
+
+

Base Medicare entitlement on age or disability.

+

Use GEQCs, DQCs (Federal employment only), and regular QCs, to determine if the requirements + are met. An individual who has worked in Medicare qualified government employment + may qualify for hospital insurance on the basis of Medicare qualified government employment + exclusively, or a combination of Medicare qualified government employment and Social + Security covered employment.

+
+
+
+
+

2. Medicare insured status based on age

+
+
+

Apply the fully insured status test for Retirement Insurance Benefits to determine + if the individual meets Medicare eligibility at age 65.

+
+
+
+
+

3. Medicare insured status based on disability

+
+
+

A number holder (NH) meets the insured status requirement for Medicare entitlement + based on disability if they:

+
    +
  1. +
    +
    a. 
    +
    +

    meet the 20/40 and fully insured requirements discussed in RS 00301.120, or

    +
    +
    +
  2. +
  3. +
    +
    b. 
    +
    +

    are disabled prior to age 31 and NH meets the special insured status requirements + discussed in RS 00301.140, or

    +
    +
    +
  4. +
  5. +
    +
    c. 
    +
    +

    are blind and NH meets the fully insured requirements discussed in RS 00301.150.

    +
    +
    +
  6. +
+

To qualify under the Medicare provision the disabled government employee must meet + the requirements for a DIB assuming the government QCs were regular QCs. Meeting the + requirements for a freeze only is not sufficient to qualify for Medicare.

+

EXAMPLE: A blind person would not meet the insured status requirements for a “freeze only” + by using the government QCs, would not be entitled to a DIB, and could not qualify + for Medicare.

+
+
+
+
+

4. End Stage Renal Disease

+
+
+

If the government worker is fully or currently insured, as described in HI 00801.191, they meet the insured status requirement for Medicare for Renal disease (R-HI) for + themselves, their spouse, or dependent child. R-HI cannot begin before the first month + the worker meets insured status requirement and the person becomes disabled, as discussed + in HI 00801.201.

+
+
+
+
+ +
+
+

E. Reference

+
+
+

HI 00801.400, Medicare entitlement for government employees

+
+
+
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301160
RS 00301.160 - Insured Status Based on Medicare Qualified Government Employment - 05/26/2011
+Batch run: 04/03/2026
+Rev:05/26/2011
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_161.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_161.html new file mode 100644 index 000000000..91d1a30d5 --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_161.html @@ -0,0 +1,296 @@ + + +SSA - POMS: RS 00301.161 - Part A Premium Reduction for Individuals with at Least 30 Quarters of Coverage (QC) - 05/26/2011 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 20 (05-11)

+

RS 00301.161 Part A Premium Reduction for Individuals with at Least 30 Quarters of Coverage (QC)

+ + +
+
+

A. Background for Part A premium reduction for individuals with at least 30 QCs

+
+
+

Section 13508 of P.L. + 103-66 Omnibus Budget Reconciliation Act of 1993 provides that the Part A premium for both + the Aged and the Working Disabled may be reduced for individuals who have at least + 30 QCs. Aged spouses or surviving spouses may qualify for the reduction if the worker + has 30 QCs. Disabled adult children (DAC) are eligible for premium reduction if they + have 30 QCs on their own record or are the spouse of a worker with 30 QCs. The DAC + of a number holder (NH) with 30 QCs is not eligible for reduction based on that NH's + earnings.

+
+
+ +
+
+

B. Policy for Part A premium reduction for individuals with at least 30 QCs

+
+
+

The reduction is effective 01/94 or, if later, the month after the month an individual + receives the 30th QC.

+

Rules in this section on crediting and allocating QCs apply in determining when an + individual meets the 30 QCs rule.

+
+
+ +
+
+

C. References

+
+
+

HI 00801.134, HI Premium Reduction for Aged Individuals with at Least 30 Quarters of Coverage

+

HI 00801.137, Initial Interview

+

HI 00801.170, Premium-HI for the Working Disabled

+

HI 01005.007, Reduced Hospital Insurance (HI) Premium

+
+
+
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301161
RS 00301.161 - Part A Premium Reduction for Individuals with at Least 30 Quarters of Coverage (QC) - 05/26/2011
+Batch run: 10/15/2026
+Rev:05/26/2011
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_200.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_200.html new file mode 100644 index 000000000..b811c3481 --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_200.html @@ -0,0 +1,297 @@ + + +SSA - POMS: RS 00301.200 - Quarters of Coverage (QC) - 07/25/1996 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 20 (05-11)

+

RS 00301.200 Quarters of Coverage (QC)

+ + +
+
+

A. Background for QCs

+
+
+

The primary use of QCs is to determine whether an individual has acquired insured + status, including freeze or DIB insured status. Use QCs to determine whether the NH + meets the:

+
    +
  1. +
    +
    a. 
    +
    +

    eligibility requirements for various benefit formulas and for various recomputations; + or

    +
    +
    +
  2. +
  3. +
    +
    b. 
    +
    +

    40 QC exception to the alien nonpayment provision, as discussed in RS 02610.010.

    +
    +
    +
  4. +
+
+
+ +
+
+

B. Policy for QCs

+
+
+

Credit QCs after 1977 based on increments of covered earnings credited to the calendar + year. For 1978, the law specifically set the increment amount at $250. For calendar + years after 1978, refer to the increment amounts chart in RS 00301.250.

+
+
+
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301200
RS 00301.200 - Quarters of Coverage (QC) - 07/25/1996
+Batch run: 10/02/2026
+Rev:07/25/1996
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_210.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_210.html new file mode 100644 index 000000000..7e7c838df --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_210.html @@ -0,0 +1,290 @@ + + +SSA - POMS: RS 00301.210 - Crediting Quarters of Coverage (QC) - 05/26/2011 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 20 (05-11)

+

RS 00301.210 Crediting Quarters of Coverage (QC) +

+ + +
+
+

A. Policy for crediting a QC +

+
+
+

Credit a QC (maximum of 4) for each increment of total earnings credited to the year. + The total earnings credited may consist of nonagricultural wages (including deemed + military wages), railroad compensation, agricultural wages, and self-employment income, + as discussed in RS 00301.220, to the maximum creditable for the year. +

+

For calendar years after 1978, the Secretary publishes (in the Federal Register on + or before November 1 of that year) the amount of earnings needed for a QC in the next + year. +

+
+
+ +
+
+

B. References +

+
+
+

RS 00301.200, Quarters of Coverage (QC) +

+

RS 00301.250, Chart of Increment Amounts +

+
+
+ + +
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301210
RS 00301.210 - Crediting Quarters of Coverage (QC) - 05/26/2011
+Batch run: 11/21/2025
+Rev:05/26/2011
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_220.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_220.html new file mode 100644 index 000000000..55ba80f9d --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_220.html @@ -0,0 +1,283 @@ + + +SSA - POMS: RS 00301.220 - Crediting of Self-Employment Income (SEI) to Calendar Years - 06/14/2013 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 20 (05-11)

+

RS 00301.220 Crediting of Self-Employment Income (SEI) to Calendar Years +

+ + +
+
+

Policy for crediting of SEI to calendar years +

+
+
+

To determine average indexed monthly earnings, average monthly wage, and quarters + of coverage, the amount of SEI derived during any taxable year that begins after 1977, + credited as follows: +

+

When a taxable year is a calendar year, or begins with or during a calendar year and + ends with or during that same calendar year, credit the SEI to that calendar year. +

+

For any other taxable year, we will allocate the SEI proportionately to the two calendars + years, portions of which are included within that taxable year, based on the number + of months in each calendar year that are completely included within the taxable year. +

+

EXAMPLE: Ann Arians has SEI of $12,000 for the taxable year beginning 10/01/87 and ending + 09/30/88. The SEI creditable for 1987 is $3,000 (3/12 x 12,000). In 1988, credit Ann + with $9,000 SEI. (9/12 x 12,000). +

+
+
+ + +
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301220
RS 00301.220 - Crediting of Self-Employment Income (SEI) to Calendar Years - 06/14/2013
+Batch run: 06/17/2013
+Rev:06/14/2013
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_230.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_230.html new file mode 100644 index 000000000..f0d7479f5 --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_230.html @@ -0,0 +1,332 @@ + + +SSA - POMS: RS 00301.230 - Assignment of Quarters of Coverage (QC) - 11/01/2023 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 58 (11-23)

+

RS 00301.230 Assignment of Quarters of Coverage (QC) +

+ + +
+
+

A. Assigning QCs +

+
+
+

For years after 1977, we treated all non-agricultural wages, agricultural wages, railroad + compensation, and self-employment income (SEI) the same for purposes of crediting + QC. The number of QCs assigned to a calendar year depends upon the amount of earnings + credited to a calendar year, regardless of the type of earnings credited. If the individual's + total earnings for the calendar year equal at least four times the quarterly increment + in effect for that year, each quarter is a QC. We assign QCs on the first day of the + each quarter. +

+
+
+ +
+
+

B. Policy for assignment of QCs +

+
+
+

Assignment of QCs is flexible. We can assign a QC to any quarter in the calendar year, + subject to the limitations in RS 00301.240. Assign a QC to a specific calendar quarter whenever necessary to meet: +

+
    +
  • +
    +
    •
    +
    +

    fully, or currently insured status discussed in RS 00301.105 through RS 00301.110, +

    + +
    +
    +
  • +
  • +
    +
    •
    +
    +

    disability insured status discussed in RS 00301.120 through RS 00301.140, and +

    + +
    +
    +
  • +
  • +
    +
    •
    +
    +

    a computation or recomputation of the number holders (NH) Primary Insurance Amount + (PIA). +

    + +
    +
    +
  • +
+

EXAMPLE: Henry (date of birth 05/23/1948) filed for retirement insurance benefits (RIB) in + May 2010. Their last posted QC was for the fourth quarter of 2009, and they did not + work in 2010. They lacked one QC for fully insured status, and we disallowed their + claim. In December 2010, they earned $1,500 and another QC. They returned to the field + office to report their additional earnings, and they provided a pay stub as proof + of the earnings. We will assign the QC to the first quarter of 2010, and award benefits + based on the disallowed application lthey filed in May 2010, since, by our assignment + of the QC to the first quarter of 2010, Henry meets fully insured status at the time + of filing. We determine QCs by the amount of earnings credited to a calendar year + and assign them to the quarters most advantageous to the NH. +

+
+
+ + +
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301230
RS 00301.230 - Assignment of Quarters of Coverage (QC) - 11/01/2023
+Batch run: 11/01/2023
+Rev:11/01/2023
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_240.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_240.html new file mode 100644 index 000000000..982a03d1f --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_240.html @@ -0,0 +1,309 @@ + + +SSA - POMS: RS 00301.240 - When a Calendar Quarter cannot be a Quarter of Coverage (QC) - 05/17/2011 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 19 (05-11)

+

RS 00301.240 When a Calendar Quarter cannot be a Quarter of Coverage (QC)

+ + +

A calendar quarter cannot be a QC when:

+ +
    +
  1. +
    +
    1. 
    +
    +

    Quarter previously established

    + +

    Do not count a quarter as more than one QC.

    +
    +
    +
  2. +
  3. +
    +
    2. 
    +
    +

    Individual dies

    + +

    Do not count any quarter after the quarter in which an individual dies (consider wages + paid to the survivor, or number holder's (NH) estate in the quarter of death paid + to the NH and therefore, may yield a QC).

    +
    +
    +
  4. +
  5. +
    +
    3. 
    +
    +

    Disability period exists

    + +

    Except for the first and last such quarters, any quarter of which any portion is included + in a period of disability cannot be a QC. Such a period begins with the quarter of + onset and ends with the quarter in which the last disability payment is due. In the + case of a disability freeze, the period ends with the second month following the month + in which the disability ceases, as discussed in RS 00301.122.

    +
    +
    +
  6. +
  7. +
    +
    4. 
    +
    +

    A future quarter exists

    + +

    A future quarter is a quarter that has not yet commenced and; therefore, cannot be + a QC. Determine whether you should award or disallow the claim when the individual + meets insured status in a future quarter, following instruction in GN 00204.007C. and GN 01010.440A.2.

    +
    +
    +
  8. +
+
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301240
RS 00301.240 - When a Calendar Quarter cannot be a Quarter of Coverage (QC) - 05/17/2011
+Batch run: 06/15/2026
+Rev:05/17/2011
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_250.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_250.html new file mode 100644 index 000000000..12a97ba41 --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_250.html @@ -0,0 +1,1159 @@ + + +SSA - POMS: RS 00301.250 - Chart of Increment Amounts - 11/21/2025 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 62 (11-25)

+

RS 00301.250 Chart of Increment Amounts +

+ + +

The following chart contains increment amounts for the years shown.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Year

+ +
+

Increment Amount

+ +
+

Amount Required

for 4 QCs +

+ +
+

2026

+ +
+

$1,890

+ +
+

$7,560

+ +
+

2025

+ +
+

$1,810

+ +
+

$7,240

+ +
+

2024

+ +
+

$1,730

+ +
+

$6,920

+ +
+

2023

+ +
+

$1,640

+ +
+

$6,560

+ +
+

2022

+ +
+

$1,510

+ +
+

$6,040

+ +
+

2021

+ +
+

$1,470

+ +
+

$5,880

+ +
+

2020

+ +
+

$1,410

+ +
+

$5,640

+ +
+

2019

+ +
+

$1,360

+ +
+

$5,440

+ +
+

2018

+ +
+

$1,320

+ +
+

$5,280

+ +
+

2017

+ +
+

$1,300

+ +
+

$5,200

+ +
+

2016

+ +
+

$1,260

+ +
+

$5,040

+ +
+

2015

+ +
+

$1,220

+ +
+

$4,880

+ +
+

2014

+ +
+

$1,200

+ +
+

$4,800

+ +
+

2013

+ +
+

$1,160

+ +
+

$4,640

+ +
+

2012

+ +
+

$1,130

+ +
+

$4,520

+ +
+

2010 – 2011

+ +
+

$1,120

+ +
+

$4,480

+ +
+

2009

+ +
+

$1,090

+ +
+

$4,360

+ +
+

2008

+ +
+

$1,050

+ +
+

$4,200

+ +
+

2007

+ +
+

$1,000

+ +
+

$4,000

+ +
+

2006

+ +
+

$970

+ +
+

$3880

+ +
+

2005

+ +
+

$920

+ +
+

$3680

+ +
+

2004

+ +
+

$900

+ +
+

$3600

+ +
+

2003

+ +
+

$890

+ +
+

$3560

+ +
+

2002

+ +
+

$870

+ +
+

$3480

+ +
+

2001

+ +
+

$830

+ +
+

$3320

+ +
+

2000

+ +
+

$780

+ +
+

$3120

+ +
+

1999

+ +
+

$740

+ +
+

$2960

+ +
+

1998

+ +
+

$700

+ +
+

$2800

+ +
+

1997

+ +
+

$670

+ +
+

$2680

+ +
+

1996

+ +
+

$640

+ +
+

$2560

+ +
+

1995

+ +
+

$630

+ +
+

$2520

+ +
+

1994

+ +
+

$620

+ +
+

$2480

+ +
+

1993

+ +
+

$590

+ +
+

$2360

+ +
+

1992

+ +
+

$570

+ +
+

$2280

+ +
+

1991

+ +
+

$540

+ +
+

$2160

+ +
+

1990

+ +
+

$520

+ +
+

$2080

+ +
+

1989

+ +
+

$500

+ +
+

$2000

+ +
+

1988

+ +
+

$470

+ +
+

$1880

+ +
+

1987

+ +
+

$460

+ +
+

$1840

+ +
+

1986

+ +
+

$440

+ +
+

$1760

+ +
+

1985

+ +
+

$410

+ +
+

$1640

+ +
+

1984

+ +
+

$390

+ +
+

$1560

+ +
+

1983

+ +
+

$370

+ +
+

$1480

+ +
+

1982

+ +
+

$340

+ +
+

$1360

+ +
+

1981

+ +
+

$310

+ +
+

$1240

+ +
+

1980

+ +
+

$290

+ +
+

$1160

+ +
+

1979

+ +
+

$260

+ +
+

$1040

+ +
+

1978

+ +
+

$250

+ +
+

$1000

+ +
+
+ +
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301250
RS 00301.250 - Chart of Increment Amounts - 11/21/2025
+Batch run: 11/21/2025
+Rev:11/21/2025
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_301.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_301.html new file mode 100644 index 000000000..f3544adff --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_301.html @@ -0,0 +1,285 @@ + + +SSA - POMS: RS 00301.301 - Quarters of Coverage (QC) before 1978 - 10/05/2023 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 41 (10-23)

+

RS 00301.301 Quarters of Coverage (QC) before 1978 +

+ + +
+
+

A. QCs before 1978 +

+
+
+

For years before 1978, a QC is any calendar quarter beginning January 1, April 1, + July 1, or October 1, in which we paid an individual at least $50 in wages, or credited + them with at least $100 of self-employment income (SEI). +

+
+
+ +
+
+

B. Policy for QCs before 1978 +

+
+
+

SSA credits QCs on wages paid to an individual after 1936, or on SEI for taxable years + beginning after 1950.  We may use military service wage credits, or railroad compensation + to establish the QCs. +

+
+
+ + +
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301301
RS 00301.301 - Quarters of Coverage (QC) before 1978 - 10/05/2023
+Batch run: 10/05/2023
+Rev:10/05/2023
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_310.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_310.html new file mode 100644 index 000000000..b389211e8 --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_310.html @@ -0,0 +1,345 @@ + + +SSA - POMS: RS 00301.310 - Wage Quarters of Coverage (QC) - 06/23/2011 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 21 (06-11)

+

RS 00301.310 Wage Quarters of Coverage (QC) +

+ + +
+
+

A. Introduction to wage QCs +

+
+
+

A number holder (NH) acquires a QC based upon nonagricultural wages in any quarter + after 1936 through the last quarter of 1977 or the quarter of the NH's death, if earlier, + that a NH had been paid $50 or more in wages. +

+
+
+ +
+
+

B. Policy for wage QCs +

+
+
+
+
+

1. When acquired +

+
+
+

A NH acquires a QC as of the first day of a quarter for total wages paid $50 or more, + this rule does not apply to wages for agricultural labor. For more information regarding + QCs based on wages for agricultural labor, see RS 00301.320. +

+
+
+
+
+

2. More than one employer +

+
+
+

If the NH had more than one employer, it is only necessary that the total wages from + all employers is $50 or more. +

+
+
+
+
+ +
+
+

C. References +

+
+
+ +
+
+ + +
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301310
RS 00301.310 - Wage Quarters of Coverage (QC) - 06/23/2011
+Batch run: 07/29/2011
+Rev:06/23/2011
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_315.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_315.html new file mode 100644 index 000000000..6e95dd66e --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_315.html @@ -0,0 +1,447 @@ + + +SSA - POMS: RS 00301.315 - Simplified Method of Determining Quarters of Coverage (QC) for 1937 - 1950 Period - 10/06/2023 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 43 (10-23)

+

RS 00301.315 Simplified Method of Determining Quarters of Coverage (QC) for 1937 - 1950 Period +

+ + +
+
+

A. Definition of elapsed year (EY) +

+
+
+

EY is the number of years after 1950 or the year of attainment of age 21, whichever + is later, and before the year that the wage earner attained age 62 or died, whichever + is earlier. +

+

For males born before 01/02/1911, count the EY up to the year the number holder (NH) + attains age 65 or dies, whichever is earlier. For males born after 01/01/1911 through + 01/01/1913, count the EY up to 1975, or the year of death, if earlier. +

+
+
+ +
+
+

B. Policy for simplified method of determining QCs for 1937-1950 +

+
+
+
+
+

1. Requirements +

+
+
+
    +
  1. +
    +
    a. 
    +
    +

    Under the 1967 Amendments, use the simplified method if:

    + +
      +
    • +
      +
      •
      +
      +

      there are at least seven EYs; and

      + +
      +
      +
    • +
    • +
      +
      •
      +
      +

      the NH is fully insured based on the number of QCs derived under this method plus + the number of QCs credited after 1950. +

      + +
      +
      +
    • +
    + +
    +
    +
  2. +
  3. +
    +
    b. 
    +
    +

    The 1990 Amendments eliminated the seven EY test. If the worker has at least $400 + of earnings before 1951, we deem the NH to have at least one QC for the period. +

    + +
    +
    +
  4. +
+

If we find the NH is not insured or deemed to have one QC before 1951 under the simplified + method, examine their record for the 1937-1950 period to determine the number of QCs + posted. +

+

NOTE: The simplified method does not apply to disability claims. +

+
+
+
+
+

2. Effective dates +

+
+
+

This provision applies for Retirement Insurance Benefit (RIB) claims filed after 01/02/1968. + In death cases, it applies if the NH died after 01/02/1968 without being entitled + to RIB or Disability Insurance Benefits (DIB). +

+

The 1990 Amendments apply for applications effectively filed 06/1992 or later. The + NH must not be insured for Special Age 72 or Transitionally Insured benefits in the + month of filing. +

+
+
+
+
+

3. Calculation +

+
+
+

The NH is deemed to have one QC for each $400 of their total wages before 1951. Wages + before 1951 include: +

+
    +
  • +
    +
    •
    +
    +

    Remuneration credited to the earnings record (ER) (regardless of the yearly maximum), + and +

    + +
    +
    +
  • +
  • +
    +
    •
    +
    +

    gratuitous military service credits, and

    + +
    +
    +
  • +
  • +
    +
    •
    +
    +

    creditable railroad compensation.

    + +
    +
    +
  • +
+
+
+
+
+ +
+
+

C. Examples +

+
+
+
+
+

1. Insured based on simplified method +

+
+
+

John Doe born 09/08/1926 filed an application in 09/1991. They need 37 QCs to be fully + insured, and have 23 QCs after 1950. Total wages posted to their ER in the 1937-1950 + period are $5,700. The simplified method applies, as there are at least seven EYs + and we insured them by this method, 23 QCs after 1950 and 14 QCs ($5,700 divided by + $400 = 14) in the 1937-1950 period. +

+

Had there been a total of only $5,500 of wages for the 1937-1950 period, the simplified + method would not apply because 13 QCs allocated for the 1937-1950 period do not give + the NH insured status. Under these circumstances, the NH's actual QCs for the 1937-1950 + period must be determined. +

+
+
+
+
+

2. Last required QC acquired retroactive period +

+
+
+

Do not use this simplified QC method when the NH acquires the last required QC or + qualifying quarter for insured status during the retroactive period for which the + application is effective and an earlier month of entitlement is possible. As in the + example above, the NH needs 37 QCs with 14 QCs allocated to the pre-1951 period. The + NH acquired their 37th QC in the 09/1991 quarter. Office of Earnings Operations will + determine the number of QCs credited to the NH's ER in the pre-1951 period. If the + number of QCs exceeds 14, insured status and the first month for which benefits may + be payable is based on the regular method of determining QCs. +

+
+
+
+
+ + +
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301315
RS 00301.315 - Simplified Method of Determining Quarters of Coverage (QC) for 1937 - 1950 Period - 10/06/2023
+Batch run: 10/06/2023
+Rev:10/06/2023
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_320.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_320.html new file mode 100644 index 000000000..aff3ea18e --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_320.html @@ -0,0 +1,346 @@ + + +SSA - POMS: RS 00301.320 - Assignment of Quarters of Coverage (QC) based on Wages for Agricultural Labor before 1978 - 10/16/2023 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 55 (10-23)

+

RS 00301.320 Assignment of Quarters of Coverage (QC) based on Wages for Agricultural Labor before + 1978 +

+ + +
+
+

A. Policy for QCs based on wages for agricultural labor before 1978 +

+
+
+

Base QCs for agricultural labor after 1954 and before 1978 on annual amounts of wages + subject to the exception noted in RS 00301.240. The QCs were ordinarily assigned in the following manner to specific calendar quarters + that were not otherwise QCs: +

+
    +
  • +
    +
    •
    +
    +

    $400 or more paid in a calendar year-all four quarters are QCs;

    + +
    +
    +
  • +
  • +
    +
    •
    +
    +

    $300-399.99 paid in a calendar year-the last three quarters of the year are QCs;

    + +
    +
    +
  • +
  • +
    +
    •
    +
    +

    $200-299.99 paid in a calendar year-the last two quarters of the year are QCs;

    + +
    +
    +
  • +
  • +
    +
    •
    +
    +

    $100-199.99 paid in a calendar year-the last quarter of the year is a QC.

    + +
    +
    +
  • +
+
+
+

NOTE: For instructions about Flexible Assignment of QCs based on Wages for Agricultural + Labor, see RS 00301.325. +

+ +
+
+
+
+ +
+
+

B. Example +

+
+
+

Jane Doe worked on farms and in a factory during 1973. They received agricultural + wages of $101 from Mr. Brown in the early part of the year, $150 from Mr. Black, and + then they worked for Mr. Green at an hourly rate on 20 different days and received + a total of $90. +

+

In 09/1973, Jane Doe received $50 as payment for part-time work in a factory. In the + last part of the year, they again worked for Mr. Brown and received $59 for their + labor. Jane Doe has four QCs based on wages paid to them in 1973. They actually had + sufficient agricultural wages to obtain four QCs in 1973 because Mr. Brown paid them + $160 during the year, Mr. Black paid them $150, and since Mr. Green paid them for + work on a time basis on at least 20 days, the $90 they received from them is wages. + The total agricultural wages paid were $400, and they receive four QCs. +

+

However, since Jane Doe had a wage QC in 09/1973, we would normally assign the QCs + as follows: 12/1973 QC based on agricultural wages, 09/1973 based on nonagricultural + wages and 06/1973 and 03/1973 on agricultural wages. +

+

 

+
+
+ + +
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301320
RS 00301.320 - Assignment of Quarters of Coverage (QC) based on Wages for Agricultural Labor before 1978 - 10/16/2023
+Batch run: 10/16/2023
+Rev:10/16/2023
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_325.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_325.html new file mode 100644 index 000000000..9cc393b18 --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_325.html @@ -0,0 +1,313 @@ + + +SSA - POMS: RS 00301.325 - Flexible Assignment of Quarters of Coverage (QC) based on Wages for Agricultural Labor - 10/05/2023 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 40 (10-23)

+

RS 00301.325 Flexible Assignment of Quarters of Coverage (QC) based on Wages for Agricultural Labor +

+ + +
+
+

A. Policy for flexible assignment of QC based on wages for agricultural labor +

+
+
+

Agricultural QCs may be assigned to quarters other than those described in RS 00301.320, if that will give the number holder (NH) required insured status at an earlier date + to meet the QC requirements for Disability Insurance Benefits(DIB) as described in + RS 00301.120 or DIB freeze as described in RS 00301.130. +

+

Similarly, assign QCs to different quarters of the year if such action enables the + NH to meet the eligibility requirements for certain types of computations and recomputations. +

+
+
+

1. 1951 - 1954 +

+
+
+

We credit agricultural labor QCs in 1951 through 1954 as regular wage QCs.

+
+
+
+
+

2. When QC are acquired +

+
+
+

A NH acquires QCs for agricultural labor as of the first day of the quarter to which + we assign them. +

+
+
+
+
+ +
+
+

B. Example +

+
+
+

When John Doe filed for Retirement Insurance Benefit (RIB) in 03/2010, they lacked + a single QC for fully insured status. We disallowed their claim. In 11/2010, they + received $1200 in wages for services in agricultural labor and became fully insured. + We must assign the QC attributable to the $1200 for agricultural labor to the 03/2010 + quarter, and benefits are payable retroactively to 01/2010. A new application is not + required. We will award benefits based on the disallowed application filed in 03/2010, + since we fully insured the NH at the time of filing by assigning the QC to the 03/2010 + quarter. +

+
+
+ + +
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301325
RS 00301.325 - Flexible Assignment of Quarters of Coverage (QC) based on Wages for Agricultural Labor - 10/05/2023
+Batch run: 10/05/2023
+Rev:10/05/2023
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_340.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_340.html new file mode 100644 index 000000000..d80256095 --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_340.html @@ -0,0 +1,359 @@ + + +SSA - POMS: RS 00301.340 - Self-Employment Quarters of Coverage (QC) before 1978 - 10/17/2023 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 56 (10-23)

+

RS 00301.340 Self-Employment Quarters of Coverage (QC) before 1978 +

+ + +
+
+

A. Introduction to self-employment QCs before 1978 +

+
+
+

Credit a QC based upon self-employment income (SEI) for any quarter after 1950 through + the last quarter of a taxable year (TY) that began before 1978, or the quarter of + death, if earlier, that an number holder had been credited with $100 or more SEI. +

+
+
+ +
+
+

B. Policy for self-employment QCs before 1978 +

+
+
+
+
+

1. Crediting SE QCs +

+
+
+

For a self-employed person to have SEI, their net earnings from SE for a TY must have + been at least $400. If a self-employed person has $400 or more of SEI for a TY, credit + them with four QCs for that year unless a short TY is involved. For possibility of + five QCs, see RS 00301.345B. Do not credit SEI to any part of a TY beginning before 1951. +

+
+
+
+
+

2. Allocation of SE QCs +

+
+
+

Although SEI reports are annual, we credit SEI to calendar quarters to determine the + QCs. Allocate SEI as follows. +

+
+
+

a. Calendar year +

+
+
+

We credit SEI equally to each quarter of the calendar year.

+
+
+
+
+

b. Fiscal year (FY) or short TY +

+
+
+

Where the TY begins on a date other than January 1, or is less than a calendar year, + credit SEI equally to the calendar quarter in which the TY ends and to each of the + next three or fewer preceding quarters, any part of which is in the TY. +

+
+
+
+
+
+
+ +
+
+

C. Example of crediting SE QCs +

+
+
+
+
+

1. FY +

+
+
+

John Doe, an architect, reports SEI of $10,800 for the FY ending 03/31/1974. Allocate + the SEI as follows: 03/1974 - $2,700; 12/1973 - $2,700; 09/1973 - $2,700; 06/1973 + - $2,700. +

+
+
+
+
+

2. Short TY +

+
+
+

Jane Doe’s TY began 09/01/1973, and ended at their death 01/03/1974. During that TY, + Jane Doe received $10,900 in SEI. Allocate $3,600 to each of the calendar quarters + 03/1974, 12/1973 and 09/1973. +

+
+
+
+
+ + +
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301340
RS 00301.340 - Self-Employment Quarters of Coverage (QC) before 1978 - 10/17/2023
+Batch run: 10/17/2023
+Rev:10/17/2023
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_345.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_345.html new file mode 100644 index 000000000..298968261 --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_345.html @@ -0,0 +1,643 @@ + + +SSA - POMS: RS 00301.345 - Gift Quarters of Coverage (QC) - 10/06/2023 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 47 (10-23)

+

RS 00301.345 Gift Quarters of Coverage (QC) +

+ + +
+
+

A. Introduction to gift QCs +

+
+
+

If a number holder (NH) has maximum creditable earnings in a year, all quarters in + that year are QCs. Where this occurs, quarters that would not otherwise be QCs, are + gift QCs. +

+

NOTE: This policy applies for years prior to 1978. For the policy about how we credit + quarters of coverage after 1977, see “Quarters of Coverage” in RS 00301.200. +

+
+
+ +
+
+

B. Operating policy for gift QCs +

+
+
+
+
+

1. Wages +

+
+
+

All quarters in the calendar year are QCs where a person has wages of:

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Amount

+ +
+

Calendar Year

+ +
+

$ 3,000

+ +
+

1937 thru 1950

+ +
+

$ 3,600

+ +
+

1951 thru 1954

+ +
+

$ 4,200

+ +
+

1955 thru 1958

+ +
+

$ 4,800

+ +
+

1959 thru 1965

+ +
+

$ 6,600

+ +
+

1966 thru 1967

+ +
+

$ 7,800

+ +
+

1968 thru 1971

+ +
+

$ 9,000

+ +
+

1972

+ +
+

$10,800

+ +
+

1973

+ +
+

$13,200

+ +
+

1974

+ +
+

$14,100

+ +
+

1975

+ +
+

$15,300

+ +
+

1976

+ +
+

$16,500

+ +
+

1977

+ +
+
+
+
+
+
+

2. Self-employment income (SEI) or SEI-wages combination +

+
+
+

All quarters in the taxable year (TY) are QCs if a person has SEI or combined SEI + and wages of: +

+
    +
  1. +
    +
    a. 
    +
    +

    $3,600 in a TY beginning after 1950 and ending before 1955;

    + +
    +
    +
  2. +
  3. +
    +
    b. 
    +
    +

    $4,200 in a TY ending after 1954 and before 1959;

    + +
    +
    +
  4. +
  5. +
    +
    c. 
    +
    +

    $4,800 in a TY ending after 1958 and before 1966;

    + +
    +
    +
  6. +
  7. +
    +
    d. 
    +
    +

    $6,600 in a TY ending after 1965 and before 1968;

    + +
    +
    +
  8. +
  9. +
    +
    e. 
    +
    +

    $7,800 in a TY ending after 1967 and before 1972;

    + +
    +
    +
  10. +
  11. +
    +
    f. 
    +
    +

    $9,000 in a TY beginning after 1971 and before 1973;

    + +
    +
    +
  12. +
  13. +
    +
    g. 
    +
    +

    $10,800 in a TY beginning after 1972 and before 1974;

    + +
    +
    +
  14. +
  15. +
    +
    h. 
    +
    +

    $13,200 in a TY beginning after 1973 and before 1975;

    + +
    +
    +
  16. +
  17. +
    +
    i. 
    +
    +

    $14,100 in a TY beginning after 1975 and before 1975;

    + +
    +
    +
  18. +
  19. +
    +
    j. 
    +
    +

    $15,300 in a TY beginning after 1975 and before 1977; and

    + +
    +
    +
  20. +
  21. +
    +
    k. 
    +
    +

    $16,500 in a TY beginning after 1976 and before 1978.

    + +
    +
    +
  22. +
+

Beginning after 1974, if a NH has combined wages and SEI totaling an amount equal + to the contribution and benefit base in effect for any such year, each quarter, any + part of which falls in the TY, is a QC. +

+

A NH who has maximum SEI, or SEI and wages in a taxable fiscal year (FY) covering + parts of five calendar quarters will be granted as many as five QCs; although the + SEI for computation purposes will be allocated to only four calendar quarters. +

+
+
+
+
+ +
+
+

C. Examples +

+
+
+
+
+

1. FY (four QC) +

+
+
+

John Doe is paid $2,700 in wages in the third quarter of 1973. They derive net earnings + (NE) from SE of $10,600 in the FY ending 06/30/1974. Only $8,100 of the $10,600 meets + the definition of SEI in this situation. They have $10,800 in combined wages and SEI + for the four-quarter TY. John Doe is credited two QCs in 1973 and two in 1974. +

+
+
+
+
+

2. FY (five QC) +

+
+
+

Jane Doe derives SEI of $10,800 in the FY ending 05/31/1974. They had no other creditable + earnings during 1973 and 1974. Jane Doe gets five QCs including one for the second + quarter of 1973 since part of such quarter falls within the TY and since they received + the maximum creditable SEI in the TY. +

+
+
+
+
+

3. Combined SEI-wages +

+
+
+

John Q. Public derives SEI of $10,620 in the FY ending 05/31/1974. Their earnings + record shows wages of $180 in the second calendar quarter of 1974. They had no other + income in 1973 and 1974. John Public’s tax return showed that they had $10,800 in + NE from their business in the TY mentioned, but in reporting their SEI had correctly + deducted $180 wages paid in 05/1974 from their total taxable SEI. John Public gets + five QCs based on their combined wages and SEI in the TY. +

+
+
+
+
+ + +
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301345
RS 00301.345 - Gift Quarters of Coverage (QC) - 10/06/2023
+Batch run: 10/06/2023
+Rev:10/06/2023
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_350.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_350.html new file mode 100644 index 000000000..4bf6f6bf3 --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_350.html @@ -0,0 +1,487 @@ + + +SSA - POMS: RS 00301.350 - Quarters of Coverage (QC) Based on Railroad (RR) Compensation Before 1978 - 06/23/2011 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 21 (06-11)

+

RS 00301.350 Quarters of Coverage (QC) Based on Railroad (RR) Compensation Before 1978 +

+ + +
+
+

A. Operating policy for QCs based on RR compensation before 1978 +

+
+
+

If the number holder (NH) has railroad (RR) employment after 1936, and before 1978, + and there is no eligibility for, or entitlement to an annuity or a lump-sum death + payment under the Railroad Retirement Act, we may use RR compensation in determining + the number of quarters of coverage (QCs). We may also use compensation in determining + the number of QCs in freeze cases, regardless of entitlement to, or eligibility for + an RR annuity. For more information regarding Freeze Insured Status, see RS 00301.130. +

+
+
+ +
+
+

B. Related policy for QCs based on RR compensation before 1978 +

+
+
+

Since RR, employers reported on an annual, rather than a quarterly basis, special + methods of determining QCs were necessary. These methods applied both in determining + which agency had jurisdiction and in figuring QCs for Social Security purposes. +

+

The Railroad Retirement Act contains a table for computing compensation for QCs before + 1978. +

+
+
+ +
+
+

C. Exhibit of computing QCs after 1939, but before 1978 +

+
+
+

Use the following table for computing compensation for QCs after 1939, but before + 1978. +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Months of service in a calendar year after 1939

+ +
+

Less than $50

+ +
+

$50 but less than $100

+ +
+

$100 but less than $150

+ +
+

$150 but less than $200

+ +
+

$200 or More

+ +
+

1-3 months

+ +
+

0 QC

+ +
+

1 QC

+ +
+

1 QC

+ +
+

1 QC

+ +
+

1 QC

+ +
+

4-6 months

+ +
+

0 QC

+ +
+

1 QC

+ +
+

2 QC

+ +
+

2 QC

+ +
+

2 QC

+ +
+

7-9 months

+ +
+

0 QC

+ +
+

1 QC

+ +
+

2 QC

+ +
+

3 QC

+ +
+

3 QC

+ +
+

10-12 months

+ +
+

0 QC

+ +
+

1 QC

+ +
+

2 QC

+ +
+

3 QC

+ +
+

4 QC

+ +
+
+

 

+
+
+ + +
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301350
RS 00301.350 - Quarters of Coverage (QC) Based on Railroad (RR) Compensation Before 1978 - 06/23/2011
+Batch run: 06/23/2011
+Rev:06/23/2011
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_470.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_470.html new file mode 100644 index 000000000..31e6e870a --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_470.html @@ -0,0 +1,285 @@ + + +SSA - POMS: RS 00301.470 - Deemed Fully Insured Status for World War II (WW II) Veterans - 10/05/2023 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 39 (10-23)

+

RS 00301.470 Deemed Fully Insured Status for World War II (WW II) Veterans +

+ + +
+
+

A. Background for deemed fully insured status for WW II veterans +

+
+
+

We may deem, under certain circumstances, a WWII veteran who separated from active + military service before July 27, 1951, and died within three years after such separation + to have died fully insured. +

+
+
+ +
+
+

B. Operating policy for deemed fully insured status for WW II veterans +

+
+
+

This provision affords survivors insurance protection where the veteran, prevented + during their WWII service from acquiring quarters of coverage, died before they had + a chance to gain or regain an insured status. +

+
+
+ + +
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301470
RS 00301.470 - Deemed Fully Insured Status for World War II (WW II) Veterans - 10/05/2023
+Batch run: 10/05/2023
+Rev:10/05/2023
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_475.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_475.html new file mode 100644 index 000000000..2c79916fe --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_475.html @@ -0,0 +1,366 @@ + + +SSA - POMS: RS 00301.475 - Special Method of Determining Insured Status by Crediting Wage Quarters of Coverage (QC) on Earned Basis - 10/05/2023 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 38 (10-23)

+

RS 00301.475 Special Method of Determining Insured Status by Crediting Wage Quarters of Coverage + (QC) on Earned Basis +

+ + +
+
+

A. Introduction to special method of determining insured status by crediting wage QCs + on earned basis +

+
+
+

When a claimant filed an application after 04/21/1960 for monthly benefits or a lump-sum, + fully insured status could be established by crediting certain wages on an earned + rather than a paid basis if the following conditions were met. +

+
+
+ +
+
+

B. Operating policy for special method of determining insured status by crediting wage + QCs on earned basis +

+
+
+
+
+

1. Requirements +

+
+
+
    +
  1. +
    +
    a. 
    +
    +

    The wage earner (WE) was not insured under the 1-for-2 rule using the normal method + of crediting wage QCs as described in RS 00301.310, and +

    + +
    +
    +
  2. +
  3. +
    +
    b. 
    +
    +

    the number holder (NH) attained age 62 (if a woman) or age 65 (if a man) before 07/01/1957 + or died in the period 01/01/1955 through 06/30/1957 (for a lump sum death payment + to be payable under this section, the NH must have attained age 62 or 65, whichever + applies, before 07/01/1957 and died after 06/30/1957); and +

    + +
    +
    +
  4. +
  5. +
    +
    c. 
    +
    +

    they would meet the insured status requirement in A above if in the first year in + which they had any creditable earnings in covered employment, their QCs were determined + on the basis of the period during which the wages were earned rather than on the basis + of the period during which they were paid; and +

    + +
    +
    +
  6. +
  7. +
    +
    d. 
    +
    +

    the claimant furnishes proof of wages earned in the first year.

    + +
    +
    +
  8. +
+
+
+
+
+

2. Restriction +

+
+
+

Any wages reallocated based on wages earned cannot then be used to establish a QC + based on wages paid for the same year or any subsequent year. For computation purposes, + do not allocate wages to period earned. +

+
+
+
+
+

3. Benefits payable +

+
+
+

If insured status is established under this provision, monthly benefits may be payable + for months after 06/1957 based on an application filed after 04/30/1960 and before + 05/01/1961; lump-sum death applications filed in the same period are not subject to + the usual 2-years-after-death filing limitation. The normal retroactive period applies + to all claims. +

+
+
+
+
+ + +
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301475
RS 00301.475 - Special Method of Determining Insured Status by Crediting Wage Quarters of Coverage (QC) on Earned Basis - 10/05/2023
+Batch run: 10/05/2023
+Rev:10/05/2023
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_480.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_480.html new file mode 100644 index 000000000..27bea8812 --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_480.html @@ -0,0 +1,347 @@ + + +SSA - POMS: RS 00301.480 - Alternate Insured Status Test for NH's Under a Disability Before 1956 - 10/05/2023 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 37 (10-23)

+

RS 00301.480 Alternate Insured Status Test for NH's Under a Disability Before 1956 +

+ + +
+
+

A. Introduction to alternate insured status test for NH’s under a disability before 1956 +

+
+
+

The alternate Disability Insurance Benefits (DIB) insured status test is available + only to a number holder (NH) who, though under a disability, does not have 20/40 for + freeze or DIB in any quarter before 10/60 and who files an application in or after + 09/60. The NH is deemed to have DIB insured status in the first quarter in which their + waiting period could begin, if there is a quarter in which all the following requirements + are met: +

+
    +
  1. +
    +
    a. 
    +
    +

    disability began in or before that quarter;

    + +
    +
    +
  2. +
  3. +
    +
    b. 
    +
    +

    the wage earner had at least 20 quarters of coverage (QC) by the end of that quarter;

    + +
    +
    +
  4. +
  5. +
    +
    c. 
    +
    +

    all quarters beginning with 03/51 up to (but not including) that quarter are QCs and + there are at least six such QCs. +

    + +
    +
    +
  6. +
+
+
+ +
+
+

B. Operating policy for alternate insured status test for NH’s under a disability before + 1956 +

+
+
+
+
+

1. Applicability +

+
+
+

The first quarter in which a NH can meet this requirement is the 09/52 quarter (since + there must be at least six continuous QCs after 1950 and before that quarter). Thus, + the first day on which a freeze can begin under this requirement is 07/01/52, and + the last day on which it can begin is 12/31/55. +

+

The first month for which we could pay a DIB based on this alternate test is 10/60. + (However, if the NH had not attained age 50 in or before 10/ 60, entitlement could + not begin before 11/60.) +

+
+
+
+
+

2. Non-applicability +

+
+
+

This alternate insured status test does not apply for applications filed after 7/02/62 + and before 12/01/64 unless the NH was living 12/01/64 and continuously disabled from + the date of filing until 12/01/64 or, if earlier, until age 65. It is also not effective + for disabilities beginning after 1955, as any NH disabled after 1955 and meeting the + alternative test would be insured under the 20/40 rule. +

+
+
+
+
+ + +
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301480
RS 00301.480 - Alternate Insured Status Test for NH's Under a Disability Before 1956 - 10/05/2023
+Batch run: 10/05/2023
+Rev:10/05/2023
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_600.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_600.html new file mode 100644 index 000000000..43d5f567a --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_600.html @@ -0,0 +1,324 @@ + + +SSA - POMS: RS 00301.600 - Election of Coverage by Vow-of-Poverty Order - 07/21/2011 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 23 (07-11)

+

RS 00301.600 Election of Coverage by Vow-of-Poverty Order +

+ + +
+
+

A. Introduction to election of coverage by vow-of-poverty order +

+
+
+

The election of coverage by a religious order under the “vow-of-poverty provision” + may give a member of the order insured status. +

+
+
+ +
+
+

B. Procedure for election of coverage by vow-of-poverty order +

+
+
+
    +
  1. +
    +
    1. 
    +
    +

    Not previously insured - no prior application

    + +

    Apply the normal retroactive period of six months to the date of filing of the application, + written inquiry, or statement of the intent to file. +

    + +
    +
    +
  2. +
  3. +
    +
    2. 
    +
    +

    Not previously insured — prior application

    + +

    If the rules of administrative finality permit reopening a previous determination, + use the date of application and the date the wage earner (WE) acquired insured status + to determine the month of entitlement. +

    + +
    +
    +
  4. +
  5. +
    +
    3. 
    +
    +

    Fully insured prior application

    + +

    The WE may be eligible for a recalculation or re-computation because of the additional + coverage. If the rules of administrative finality permit reopening the determination + under the previous application (e.g., within 4 years), pay a retroactive increased + benefit. If not, the increase in benefits will be payable prospectively only. +

    + +
    +
    +
  6. +
+
+
+ + +
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301600
RS 00301.600 - Election of Coverage by Vow-of-Poverty Order - 07/21/2011
+Batch run: 07/21/2011
+Rev:07/21/2011
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_800.html b/tests/data/track_b/insured_status_sources/poms_rs_00301_800.html new file mode 100644 index 000000000..a28107784 --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_800.html @@ -0,0 +1,268 @@ + + +SSA - POMS: RS 00301.800 - Quarters of Coverage Requirements - Exhibit - 08/10/2012 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + +

Program Operations Manual System (POMS)

+ + +
+ + + +
+ +
+ +
+
+ + +
+

TN 14 (04-89)

+

RS 00301.800 Quarters of Coverage Requirements - Exhibit +

+ + +
+ +
+

Quarters of Coverage Requirements (Back) - Exhibit

+ +
+
+
+ +
+
+
+ + +
To Link to this section - Use this URL:
http://policy.ssa.gov/poms.nsf/lnx/0300301800
RS 00301.800 - Quarters of Coverage Requirements - Exhibit - 08/10/2012
+Batch run: 02/05/2018
+Rev:08/10/2012
+
+ + +
+ + +
+ + +
+ + + + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + diff --git a/tests/data/track_b/insured_status_sources/ssa_oact_qc.txt b/tests/data/track_b/insured_status_sources/ssa_oact_qc.txt new file mode 100644 index 000000000..ba029641f --- /dev/null +++ b/tests/data/track_b/insured_status_sources/ssa_oact_qc.txt @@ -0,0 +1,160 @@ +Automatic Determinations + Employment coverage thresholds + Wage-indexed amounts + + Latest amount & QC explanation + The amount of earnings required for a quarter of coverage (QC) in 2027 is + $1,970. "Quarter of coverage" is a + legal term, + but you may also see the term "Social Security credit" (or just "credit") used + elsewhere. A QC is the basic unit for determining whether a worker is + insured under the Social Security program. + No matter how high your earnings may be, you can not earn more than 4 QC's in + one year. + History + See historical series of earnings needed + to earn one quarter of coverage, 1978-2027. + + For years before 1978, an individual generally was credited with a quarter of + coverage for each quarter in which wages of $50 or more were paid, or an + individual was credited with 4 quarters of coverage for every taxable year in + which $400 or more of self-employment income was earned. Beginning in 1978, + employers generally report wages on an annual, instead of quarterly, basis. + With this change to annual reporting, the law provided that a quarter of + coverage be credited for each $250 of an individual's total wages and + self-employment income for calendar year 1978 (up to a maximum of 4 quarters + of coverage for the year). After 1978, the amount of earnings needed for a + quarter of coverage changes automatically each year with changes in the + national average wage index. + Determination of the quarter of coverage amount for 2027 + The law specifies that the quarter of coverage (QC) amount for 2027 is + equal to the 1978 amount of $250 multiplied by the ratio of the + national average wage index for 2025 to that for + 1976, or, if larger, the 2026 amount of $1,890. If the amount so + determined is not a multiple of $10, it shall be rounded to the nearest + multiple of $10. + + Calculation details + + Amounts informula + 1978 earnings for one QC$250 + 1976 average wage index9,226.48 + + 2025 average wage index72,800.33 + + Computation$250 times 72,800.33 divided by 9,226.48 + equals $1,972.59, which rounds to $1,970 + + Higher amount$1,970 exceeds the amount for 2026, + so the earnings needed to earn one QC in 2027 is $1,970 + + Amount of earnings needed to earn one quarter of coverage + + Year + Earnings + 1978 + $250 + 1979 + 260 + 1980 + 290 + 1981 + 310 + 1982 + 340 + 1983 + 370 + 1984 + 390 + 1985 + 410 + 1986 + 440 + 1987 + 460 + 1988 + 470 + 1989 + 500 + 1990 + 520 + 1991 + 540 + 1992 + 570 + 1993 + 590 + 1994 + 620 + 1995 + 630 + 1996 + 640 + 1997 + 670 + + Year + Earnings + 1998 + $700 + 1999 + 740 + 2000 + 780 + 2001 + 830 + 2002 + 870 + 2003 + 890 + 2004 + 900 + 2005 + 920 + 2006 + 970 + 2007 + 1,000 + 2008 + 1,050 + 2009 + 1,090 + 2010 + 1,120 + 2011 + 1,120 + 2012 + 1,130 + 2013 + 1,160 + 2014 + 1,200 + 2015 + 1,220 + 2016 + 1,260 + 2017 + 1,300 + + Year + Earnings + 2018 + $1,320 + 2019 + 1,360 + 2020 + 1,410 + 2021 + 1,470 + 2022 + 1,510 + 2023 + 1,640 + 2024 + 1,730 + 2025 + 1,810 + 2026 + 1,890 + 2027 + 1,970 \ No newline at end of file diff --git a/tests/estimates/test_birth_evidence_artifact.py b/tests/estimates/test_birth_evidence_artifact.py index 270e8917b..ca17ee794 100644 --- a/tests/estimates/test_birth_evidence_artifact.py +++ b/tests/estimates/test_birth_evidence_artifact.py @@ -183,6 +183,8 @@ def test_post_review_sources_are_outside_historical_reducer_identity(): Path("src/populace_dynamics/track_b/reconstructed.py"), Path("src/populace_dynamics/track_b/gross_benefits.py"), Path("src/populace_dynamics/track_b/_provenance.py"), + Path("src/populace_dynamics/track_b/insured_status.py"), + Path("src/populace_dynamics/track_b/_insured_status_qc.py"), Path("src/populace_dynamics/track_b/ret_grace.py"), Path("src/populace_dynamics/track_b/ret_ledger.py"), Path("src/populace_dynamics/track_b/arf.py"), @@ -387,6 +389,8 @@ def test_post_review_exclusions_are_unreachable_from_birth_evidence(): "populace_dynamics.track_b.reconstructed", "populace_dynamics.track_b.gross_benefits", "populace_dynamics.track_b._provenance", + "populace_dynamics.track_b.insured_status", + "populace_dynamics.track_b._insured_status_qc", "populace_dynamics.track_b.ret_grace", "populace_dynamics.track_b.ret_ledger", "populace_dynamics.track_b.arf", diff --git a/tests/test_track_b_gross_benefits_fix_round_13_audit.py b/tests/test_track_b_gross_benefits_fix_round_13_audit.py index fd66f39e0..a9167d4fd 100644 --- a/tests/test_track_b_gross_benefits_fix_round_13_audit.py +++ b/tests/test_track_b_gross_benefits_fix_round_13_audit.py @@ -14,6 +14,7 @@ from collections.abc import Mapping from copy import copy, deepcopy from dataclasses import fields, is_dataclass, replace +from datetime import date from decimal import Decimal from enum import Enum from fractions import Fraction as F @@ -27,6 +28,7 @@ from populace_dynamics.track_b import _provenance as provenance from populace_dynamics.track_b import arf as a from populace_dynamics.track_b import gross_benefits as g +from populace_dynamics.track_b import insured_status as insured from populace_dynamics.track_b import recompute as c from populace_dynamics.track_b import ret_grace as grace from populace_dynamics.track_b import ret_ledger as ret @@ -366,6 +368,17 @@ def _declaration_cases(): for _, factory, _, _, _ in MUTATION_CASES: value = factory() cases[type(value).__name__] = value + cases.update( + { + "Person": insured.Person(date(2000, 1, 2)), + "CoverageYear": insured.CoverageYear( + insured.EarningsProvenance.OBSERVED, qc_count=4 + ), + "DisabilityPeriod": insured.DisabilityPeriod( + date(2020, 1, 1), date(2021, 1, 1) + ), + } + ) return cases @@ -465,6 +478,31 @@ def _sealed_samples(): 2026, grace.GraceYearState(), [grace.GraceMonth()] * 12 ) samples["RecomputationDecision"] = c.recomputation_decision(1, 2) + person = insured.Person(date(2026, 1, 2)) + years = { + 2026: insured.CoverageYear( + insured.EarningsProvenance.OBSERVED, qc_count=0 + ) + } + result = insured.insured_status(person, years, date(2026, 1, 1)) + samples["InsuredStatus"] = result + samples["StatusDecision"] = result.fully + samples["DLIRange"] = result.dli + samples["InsuredOutcome"] = insured.evaluate_insured_status( + "supported-insured", 1, lambda: result + ) + samples["InsuredConfigurationUnsupported"] = ( + insured.evaluate_insured_status( + "unsupported-insured", + 1, + lambda: insured.insured_status( + person, + years, + date(2026, 1, 1), + totalization_credits=("foreign-system",), + ), + ).unsupported + ) return samples @@ -489,6 +527,11 @@ def _sealed_samples(): "RecomputationDecision", "RecomputationResult", "RecomputationOutcome", + "InsuredConfigurationUnsupported", + "StatusDecision", + "DLIRange", + "InsuredStatus", + "InsuredOutcome", ) diff --git a/tests/test_track_b_gross_benefits_fix_round_15_arguments.py b/tests/test_track_b_gross_benefits_fix_round_15_arguments.py index 5fc3cd81f..c95b07353 100644 --- a/tests/test_track_b_gross_benefits_fix_round_15_arguments.py +++ b/tests/test_track_b_gross_benefits_fix_round_15_arguments.py @@ -4,16 +4,19 @@ """ from dataclasses import fields +from datetime import date import pytest from hypothesis import given, settings from hypothesis import strategies as st from populace_dynamics.track_b import gross_benefits as g +from populace_dynamics.track_b import insured_status as insured from tests.test_track_b_gross_benefits_fix_round_12_contract import ( - COMPUTE, - EVALUATE, - _outcome, + COMPUTE as PAYMENT_COMPUTE, +) +from tests.test_track_b_gross_benefits_fix_round_12_contract import ( + EVALUATE as PAYMENT_EVALUATE, ) from tests.test_track_b_gross_benefits_fix_round_15_receivers import Foreign from tests.test_track_b_input_schema import ( @@ -29,6 +32,33 @@ ) +def _insured_status(*, refused=False): + return insured.insured_status( + insured.Person(date(2026, 1, 2)), + { + 2026: insured.CoverageYear( + insured.EarningsProvenance.OBSERVED, qc_count=0 + ) + }, + date(2026, 1, 1), + test=insured.InsuredTest.FULLY, + totalization_credits=("foreign-credit",) if refused else (), + ) + + +COMPUTE = {**PAYMENT_COMPUTE, "insured_status": _insured_status} +EVALUATE = { + **PAYMENT_EVALUATE, + "insured_status": insured.evaluate_insured_status, +} + + +def _outcome(layer, *, refused=False): + return EVALUATE[layer]( + f"{layer}-{refused}", 1, lambda: COMPUTE[layer](refused=refused) + ) + + def _layer(module_name): name = module_name.rsplit(".", 1)[-1] return { diff --git a/tests/test_track_b_gross_benefits_fix_round_15_receivers.py b/tests/test_track_b_gross_benefits_fix_round_15_receivers.py index 5293cc7bf..8dbaf8565 100644 --- a/tests/test_track_b_gross_benefits_fix_round_15_receivers.py +++ b/tests/test_track_b_gross_benefits_fix_round_15_receivers.py @@ -17,6 +17,28 @@ LAYERS, _outcome, ) +from tests.test_track_b_gross_benefits_fix_round_13_audit import ( + _declaration_cases, + _sealed_samples, +) + + +@pytest.fixture(autouse=True) +def _restore_hypothesis_settings_after_parameter(request): + # The pinned pytest plugin replaces this setting with a child for each + # parameter, but does not restore its parent. With derandomize=True the + # database is None, so settings.database recursively traverses every + # parent instead of caching. A Hypothesis-only reproducer (no repository + # imports) raises RecursionError after 998 such parents. Preserve the + # original settings between parameters; keep every case and health check. + original = getattr( + request.function, "_hypothesis_internal_use_settings", None + ) + try: + yield + finally: + if original is not None: + request.function._hypothesis_internal_use_settings = original class Foreign: @@ -212,13 +234,11 @@ def test_nested_evaluator_rejects_foreign_callback_result_without_class_hook(): @pytest.fixture(scope="module") def reader_samples(): from tests.test_track_b_gross_benefits_fix_round_10_api import _world - from tests.test_track_b_gross_benefits_fix_round_13_audit import ( - _sealed_samples, - ) from tests.test_track_b_r3_fix_round_13 import MUTATION_CASES samples, _, guard = _world(100) samples.update(_sealed_samples()) + samples.update(_declaration_cases()) samples[type(guard).__name__] = guard for _, factory, _, _, _ in MUTATION_CASES: value = factory() diff --git a/tests/test_track_b_input_schema.py b/tests/test_track_b_input_schema.py index 2e2d30586..0eb530d33 100644 --- a/tests/test_track_b_input_schema.py +++ b/tests/test_track_b_input_schema.py @@ -21,6 +21,7 @@ from populace_dynamics.track_b import _provenance as provenance from populace_dynamics.track_b import arf as a from populace_dynamics.track_b import gross_benefits as g +from populace_dynamics.track_b import insured_status as insured from populace_dynamics.track_b import recompute as r from populace_dynamics.track_b import ret_grace as grace from populace_dynamics.track_b import ret_ledger as ret @@ -420,7 +421,7 @@ def test_valid_review_controls_keep_their_original_refusal_and_money(layer): ) -MODULES = (g, grace, ret, a, r) +MODULES = (g, grace, ret, a, r, insured) GUARD_PROPERTIES = tuple( name for name, descriptor in vars(g.SavingsClauseGuard).items() @@ -470,6 +471,22 @@ def public_world(): layer: (EVALUATE[layer]("valid", 1, COMPUTE[layer]),) for layer in LAYERS } + insured_person = insured.Person(date(2000, 1, 2)) + insured_years = { + year: insured.CoverageYear( + insured.EarningsProvenance.OBSERVED, qc_count=4 + ) + for year in range(2000, 2027) + } + + def compute_insured(): + return insured.insured_status( + insured_person, + insured_years, + date(2026, 1, 1), + test=insured.InsuredTest.FULLY, + ) + return { g: g_world, grace: { @@ -532,6 +549,19 @@ def public_world(): "death_month": None, "fra_month": None, }, + insured: { + "nawi": F("72800.33"), + "prior_amount": 1890, + "person": insured_person, + "years": insured_years, + "month": date(2026, 1, 1), + "test": insured.InsuredTest.FULLY, + "coverage_end_month": None, + "totalization_credits": (), + "key": "valid-insured", + "weight": F(1), + "compute": compute_insured, + }, } @@ -1207,7 +1237,16 @@ def counted(original): if not inspect.isfunction(reader): continue arguments = set(inspect.signature(reader).parameters) - {"self"} - inherited = INHERITED_METHOD_ARGUMENTS.get(cls.__name__, {}) + inherited = INHERITED_METHOD_ARGUMENTS.get( + cls.__name__, + ( + INHERITED_METHOD_ARGUMENTS[ + "FamilyConfigurationUnsupported" + ] + if issubclass(cls, g.FamilyConfigurationUnsupported) + else {} + ), + ) if name in inherited: assert arguments == set(inherited[name]) kwargs = inherited[name] diff --git a/tests/test_track_b_insured_status.py b/tests/test_track_b_insured_status.py new file mode 100644 index 000000000..6dcc311fa --- /dev/null +++ b/tests/test_track_b_insured_status.py @@ -0,0 +1,929 @@ +"""Insured-status statutory conformance on invented and captured cases. + +No population, behavioral, or forecast claim. Every history explicitly +states provenance, including the zero years before a worked record begins. +""" + +import pickle +import re +import xml.etree.ElementTree as ET +from copy import copy, deepcopy +from dataclasses import replace +from datetime import date +from fractions import Fraction +from pathlib import Path + +import pytest +from hypothesis import given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as i +from populace_dynamics.track_b.gross_benefits import ( + InvalidFamilyInput, + count_family_outcomes, +) + +SOURCES = Path(__file__).parent / "data/track_b/insured_status_sources" +PROPERTY = settings(max_examples=25, deadline=None) + + +def declared(count=0, *, provenance=None, convention_id=None, year=2000): + provenance = provenance or i.EarningsProvenance.OBSERVED + if provenance is i.EarningsProvenance.UNKNOWN: + return i.CoverageYear(provenance) + values = {"qc_count": count} + if year < 1978: + values = {"qc_quarters": tuple(n < count for n in range(4))} + return i.CoverageYear(provenance, convention_id=convention_id, **values) + + +def history(person, month, counts=None, *, end=None): + counts = counts or {} + last = min(month.year, end.year) if end else month.year + if person.death_date is not None: + last = min(last, person.death_date.year) + return { + year: declared(counts.get(year, 0), year=year) + for year in range(max(1937, person.birth_date.year), last + 1) + } + + +def compute(person, month, counts=None, **kwargs): + return i.insured_status( + person, + history(person, month, counts, end=kwargs.get("coverage_end_month")), + month, + **kwargs, + ) + + +def qid(year, quarter): + return year * 4 + quarter - 1 + + +def statuses(result): + return tuple( + getattr(result, name).insured + for name in ("fully", "currently", "disability") + ) + + +def test_version_and_explicit_zero_history(): + person = i.Person(date(1990, 5, 2)) + result = compute(person, date(2026, 12, 1)) + assert result.version == "track-b-insured-v1" + assert not any(statuses(result)) + assert result.fully.required == 14 + assert result.currently.required == 6 + assert result.disability.required == 20 + assert result.unknown_years == () + assert result.convention_years == {} + assert not result.decided_despite_unknowns + assert set(result.qcs_by_year.values()) == {(0, 0)} + + +def test_fred_brown_35_quarters_require_17_poms_140_example_1(): + person = i.Person(date(1958, 5, 13), disability_onset=date(1988, 1, 15)) + result = compute( + person, + date(1988, 1, 1), + {1980: 4, 1981: 4, 1982: 4, 1983: 4, 1984: 1}, + ) + assert result.disability.required == 17 + assert len(result.disability.window) == 35 + assert result.disability.window[0] == qid(1979, 3) + assert result.disability.window[-1] == qid(1988, 1) + assert result.disability.insured + + +def test_sam_white_6_in_12_poms_140_example_2(): + person = i.Person(date(1961, 8, 20), disability_onset=date(1984, 4, 12)) + result = compute(person, date(1984, 4, 1), {1982: 4, 1983: 2}) + assert result.disability.required == 6 + assert result.disability.window == tuple( + range(qid(1981, 3), qid(1984, 2) + 1) + ) + assert result.disability.insured + + +@pytest.mark.parametrize( + "counts,expected", + [ + ({1984: 4, 1985: 2}, True), + ({1981: 4, 1982: 1, 1983: 1, 1984: 3}, False), + ({1982: 3, 1984: 4, 1985: 1}, True), + ], + ids=["mary-example-3", "mary-example-4", "mary-example-5-moveable"], +) +def test_mary_smith_special_window_poms_140_examples_3_to_5(counts, expected): + person = i.Person(date(1964, 11, 15), disability_onset=date(1985, 8, 30)) + result = compute(person, date(1985, 8, 1), counts) + assert result.disability.required == 6 + assert result.disability.window == tuple( + range(qid(1982, 4), qid(1985, 3) + 1) + ) + assert result.disability.insured is expected + + +def test_dli_1990_june_poms_148_example(): + person = i.Person(date(1954, 3, 9)) + counts = { + 1973: 2, + 1975: 4, + 1976: 4, + 1980: 2, + 1981: 2, + 1982: 4, + 1985: 4, + 1986: 4, + 1987: 2, + 1988: 2, + } + result = compute(person, date(1991, 12, 1), counts) + assert sum(pair[0] for pair in result.qcs_by_year.values()) == 30 + assert i.fully_insured_requirement(person, date(1990, 6, 1)) == 14 + assert result.dli.lower == result.dli.upper == date(1990, 6, 30) + assert not result.dli.right_censored + at_dli = compute(person, date(1990, 6, 1), counts) + after_dli = compute(person, date(1990, 7, 1), counts) + assert at_dli.disability.insured + assert not after_dli.disability.insured + + +def test_calvin_hill_blind_clock_poms_150_example(): + person = i.Person( + date(1957, 7, 12), + disability_onset=date(1957, 7, 12), + statutory_blindness=True, + ) + counts = {1977: 2, 1982: 1, 1983: 1, 1985: 1, 1986: 2} + first = history(person, date(1986, 1, 1), counts) + first[1977] = i.CoverageYear( + i.EarningsProvenance.OBSERVED, + qc_quarters=(False, False, True, True), + ) + march = i.insured_status(person, first, date(1986, 3, 1)) + april = i.insured_status(person, first, date(1986, 4, 1)) + assert march.fully.required == april.fully.required == 7 + assert march.fully.qc_count_lower == 6 + assert not march.disability.insured + assert april.fully.qc_count_lower == 7 + assert april.disability.insured + + +def test_fully_requirement_differential_cfr_404_115_every_captured_row(): + document = ET.parse(SOURCES / "ecfr_20cfr404_subpart_b.xml") + section = next(d for d in document.iter("DIV8") if d.get("N") == "404.115") + tested = 0 + for row in section.findall(".//TBODY/TR"): + cells = [ + "".join(cell.itertext()).strip() for cell in row.findall("TD") + ] + if not cells: + continue + years = [int(value) for value in re.findall(r"\b\d{4}\b", cells[0])] + if "or earlier" in cells[0]: + births = (date(years[0], 1, 1),) + elif "or later" in cells[0]: + births = (date(years[0], 1, 2), date(1960, 1, 2)) + else: + births = (date(years[0], 1, 2), date(years[1], 1, 1)) + for birth in births: + for sex, cell in ( + (i.Sex.MALE, cells[1]), + (i.Sex.FEMALE, cells[2]), + ): + if not cell: + continue + assert i.fully_insured_requirement( + i.Person(birth, sex=sex), date(2026, 12, 1) + ) == int(cell) + tested += 1 + assert tested >= 140 + + +def test_elapsed_years_from_birth_not_projection_entry(): + person = i.Person(date(1980, 2, 2)) + assert i.fully_insured_requirement(person, date(2026, 1, 1)) == 24 + result = compute(person, date(2026, 1, 1), {2024: 4, 2025: 4, 2026: 1}) + assert not result.fully.insured + assert result.fully.required == 24 + + +def test_fully_requirement_excludes_partial_disability_years_cfr_example(): + plain = i.Person(date(1935, 1, 2)) + frozen = replace( + plain, + prior_disability_periods=( + i.DisabilityPeriod(date(1975, 12, 5), date(1977, 1, 31)), + ), + ) + month = date(1980, 1, 1) + assert ( + i.fully_insured_requirement(plain, month) + - i.fully_insured_requirement(frozen, month) + == 3 + ) + + +def test_unknown_is_never_zero_and_named_refusal_stays_in_denominator(): + person = i.Person(date(2000, 2, 2)) + month = date(2026, 12, 1) + years = history(person, month, {2025: 4}) + years[2024] = declared(provenance=i.EarningsProvenance.UNKNOWN) + outcome = i.evaluate_insured_status( + "unknown", + Fraction(3, 2), + lambda: i.insured_status( + person, years, month, test=i.InsuredTest.FULLY + ), + ) + assert not outcome.supported + assert ( + outcome.unsupported.reason.value + == "unknown_earnings_years_decide_status" + ) + denominator = count_family_outcomes((outcome,)) + assert denominator.rows == denominator.unsupported_rows == 1 + assert ( + denominator.weight == denominator.unsupported_weight == Fraction(3, 2) + ) + + +def test_decided_despite_unknown_reports_range_and_unknown_years(): + person = i.Person(date(2000, 2, 2)) + month = date(2026, 12, 1) + years = history(person, month, {2025: 4, 2026: 4}) + years[2024] = declared(provenance=i.EarningsProvenance.UNKNOWN) + result = i.insured_status(person, years, month, test=i.InsuredTest.FULLY) + assert result.fully.insured + assert result.decided_despite_unknowns + assert result.unknown_years == (2024,) + assert result.fully.qc_count_lower == 8 + assert result.fully.qc_count_upper == 12 + assert result.qcs_by_year[2024] == (0, 4) + + +def test_missing_year_and_provenance_are_input_errors(): + person = i.Person(date(2000, 2, 2)) + month = date(2026, 12, 1) + years = history(person, month) + del years[2010] + with pytest.raises(InvalidFamilyInput): + i.insured_status(person, years, month) + with pytest.raises((InvalidFamilyInput, TypeError)): + i.CoverageYear(qc_count=0) + with pytest.raises(InvalidFamilyInput): + i.CoverageYear("observed", qc_count=0) + with pytest.raises(InvalidFamilyInput): + i.CoverageYear(i.EarningsProvenance.UNKNOWN, qc_count=0) + with pytest.raises(InvalidFamilyInput): + i.CoverageYear(i.EarningsProvenance.CONVENTION_FILLED, qc_count=0) + + +@pytest.mark.parametrize( + "change", + [ + {"qc_count": 1, "wages": Fraction(1)}, + {"qc_count": True}, + {"qc_count": 5}, + ], +) +def test_ambiguous_or_malformed_direct_coverage_is_input_error(change): + with pytest.raises(InvalidFamilyInput): + i.CoverageYear(i.EarningsProvenance.OBSERVED, **change) + + +def test_before_1978_direct_qcs_require_quarter_flags(): + person = i.Person(date(1950, 2, 2)) + month = date(1977, 12, 1) + years = history(person, month) + years[1977] = i.CoverageYear(i.EarningsProvenance.OBSERVED, qc_count=2) + with pytest.raises(InvalidFamilyInput): + i.insured_status(person, years, month) + + +def test_totalization_is_named_refusal_and_empty_changes_nothing(): + person = i.Person(date(1990, 2, 2)) + month = date(2026, 12, 1) + years = history(person, month) + assert i.insured_status(person, years, month) == i.insured_status( + person, years, month, totalization_credits=() + ) + outcome = i.evaluate_insured_status( + "foreign", + Fraction(1), + lambda: i.insured_status( + person, years, month, totalization_credits=("UK:2020",) + ), + ) + assert ( + outcome.unsupported.reason.value == "totalization_credits_unsupported" + ) + + +def test_exit_freezes_credits_but_recent_work_clocks_continue(): + person = i.Person(date(1980, 2, 2)) + exit_month = date(2020, 12, 1) + counts = {year: 4 for year in range(2011, 2021)} + years = history(person, exit_month, counts) + before = i.insured_status( + person, years, exit_month, coverage_end_month=exit_month + ) + after = i.insured_status( + person, years, date(2031, 1, 1), coverage_end_month=exit_month + ) + assert statuses(before) == (True, True, True) + assert statuses(after) == (True, False, False) + assert after.fully.required > before.fully.required + assert after.qcs_by_year == before.qcs_by_year + invalid = dict(years, **{}) + invalid[2021] = declared() + with pytest.raises(InvalidFamilyInput): + i.insured_status( + person, invalid, date(2031, 1, 1), coverage_end_month=exit_month + ) + + +def test_results_outcomes_and_denominators_are_sealed(): + person = i.Person(date(2000, 2, 2)) + result = compute(person, date(2026, 12, 1)) + outcome = i.evaluate_insured_status("sealed", Fraction(1), lambda: result) + denominator = count_family_outcomes((outcome,)) + for value in (result, result.fully, result.dli, outcome, denominator): + for operation in (copy, deepcopy, replace, pickle.dumps): + with pytest.raises(InvalidFamilyInput): + operation(value) + + +@PROPERTY +@given( + st.lists(st.integers(0, 4), min_size=10, max_size=10), + st.integers(0, 9), + st.sampled_from([1980, 1990, 2000]), +) +def test_property_status_and_dli_monotone_in_quarters( + counts, index, birth_year +): + person = i.Person(date(birth_year, 2, 2)) + month = date(2026, 12, 1) + lower = dict(zip(range(2017, 2027), counts, strict=True)) + upper = dict(lower) + upper[2017 + index] = min(4, upper[2017 + index] + 1) + left = compute(person, month, lower) + right = compute(person, month, upper) + assert all( + not old or new + for old, new in zip(statuses(left), statuses(right), strict=True) + ) + assert (right.dli.lower or date.min) >= (left.dli.lower or date.min) + assert (right.dli.upper or date.min) >= (left.dli.upper or date.min) + assert not left.disability.insured or left.fully.insured + assert not right.disability.insured or right.fully.insured + + +@PROPERTY +@given( + st.lists(st.integers(0, 4), min_size=10, max_size=10), st.integers(0, 9) +) +def test_property_unknown_bounds_cover_every_filling(counts, index): + person = i.Person(date(1990, 2, 2)) + month = date(2026, 12, 1) + years = history( + person, month, dict(zip(range(2017, 2027), counts, strict=True)) + ) + unknown_year = 2017 + index + years[unknown_year] = declared(provenance=i.EarningsProvenance.UNKNOWN) + for selected, field in ( + (i.InsuredTest.FULLY, "fully"), + (i.InsuredTest.CURRENTLY, "currently"), + (i.InsuredTest.DISABILITY, "disability"), + ): + outcome = i.evaluate_insured_status( + "bounds", + Fraction(1), + lambda selected=selected: i.insured_status( + person, years, month, test=selected + ), + ) + concrete = [] + concrete_dates = [] + for filling in range(5): + filled = dict(years) + filled[unknown_year] = declared(filling) + computed = i.insured_status(person, filled, month, test=selected) + concrete.append(getattr(computed, field)) + if computed.dli is not None: + concrete_dates.append(computed.dli.lower or date.min) + if outcome.supported: + decision = getattr(outcome.result, field) + assert all(row.insured is decision.insured for row in concrete) + assert all( + decision.qc_count_lower + <= row.qc_count_lower + <= decision.qc_count_upper + for row in concrete + ) + if concrete_dates: + assert all( + (outcome.result.dli.lower or date.min) + <= concrete_date + <= (outcome.result.dli.upper or date.min) + for concrete_date in concrete_dates + ) + else: + assert ( + outcome.unsupported.reason.value + == "unknown_earnings_years_decide_status" + ) + assert len({row.insured for row in concrete}) == 2 + + +@PROPERTY +@given(st.lists(st.integers(0, 4), min_size=10, max_size=10)) +def test_property_convention_equal_amounts_and_order_independence(counts): + person = i.Person(date(1990, 2, 2)) + month = date(2026, 12, 1) + years = history( + person, month, dict(zip(range(2017, 2027), counts, strict=True)) + ) + observed = i.insured_status(person, years, month) + reversed_result = i.insured_status( + person, dict(reversed(tuple(years.items()))), month + ) + assert observed == reversed_result + filled = { + year: replace( + row, + provenance=i.EarningsProvenance.CONVENTION_FILLED, + convention_id="invented-zero-and-counts-v1", + ) + for year, row in years.items() + } + convention = i.insured_status(person, filled, month) + assert statuses(observed) == statuses(convention) + assert observed.qcs_by_year == convention.qcs_by_year + assert observed.dli == convention.dli + assert convention.convention_years == { + year: "invented-zero-and-counts-v1" for year in years + } + assert i.insured_status(person, years, month) == observed + + +@PROPERTY +@given(st.integers(1930, 2000), st.integers(1, 4)) +def test_property_windows_and_blindness_rule(birth_year, quarter): + person = i.Person(date(birth_year, 2, 2)) + month = date(2026, quarter * 3, 1) + counts = {year: 4 for year in range(max(birth_year, 1990), 2026)} + ordinary = compute(person, month, counts) + blind = compute(replace(person, statutory_blindness=True), month, counts) + assert len(ordinary.currently.window) == 13 + assert len(set(ordinary.currently.window)) == 13 + assert 6 <= ordinary.fully.required <= 40 + if ordinary.disability.rule == "under31_special": + assert qid(2026, quarter) < qid(birth_year + 31, 1) + if birth_year <= 1995: + assert ordinary.disability.required == 20 + assert len(ordinary.disability.window) == 40 + assert blind.disability.insured is blind.fully.insured + + +@PROPERTY +@given(st.integers(1, 30), st.integers(0, 5)) +def test_property_input_errors_are_atomic_before_refusal( + weight, missing_offset +): + person = i.Person(date(2000, 2, 2)) + month = date(2026, 12, 1) + years = history(person, month) + del years[2000 + missing_offset] + with pytest.raises(InvalidFamilyInput): + i.evaluate_insured_status( + "invalid", + Fraction(weight), + lambda: i.insured_status( + person, years, month, totalization_credits=("foreign",) + ), + ) + + +@PROPERTY +@given(st.integers(0, 100), st.integers(0, 100)) +def test_property_refusal_denominator_conserves_rows_and_weights(left, right): + person = i.Person(date(2000, 2, 2)) + month = date(2026, 12, 1) + years = history(person, month) + supported = i.evaluate_insured_status( + "supported", + Fraction(left, 3), + lambda: i.insured_status(person, years, month), + ) + refused = i.evaluate_insured_status( + "refused", + Fraction(right, 7), + lambda: i.insured_status( + person, years, month, totalization_credits=("foreign",) + ), + ) + rows = (supported, refused) + denominator = count_family_outcomes(rows) + assert denominator == count_family_outcomes(tuple(reversed(rows))) + assert ( + denominator.rows + == denominator.supported_rows + denominator.unsupported_rows + == 2 + ) + assert ( + denominator.weight + == denominator.supported_weight + denominator.unsupported_weight + == Fraction(left, 3) + Fraction(right, 7) + ) + + +@PROPERTY +@given( + st.integers(2010, 2023), + st.lists(st.integers(0, 4), min_size=2, max_size=2), +) +def test_property_disability_period_exclusion_never_adds_qcs( + start_year, counts +): + person = i.Person(date(1980, 2, 2)) + frozen = replace( + person, + prior_disability_periods=( + i.DisabilityPeriod( + date(start_year, 4, 2), date(start_year + 1, 8, 2) + ), + ), + ) + month = date(2026, 12, 1) + annual = {start_year: counts[0], start_year + 1: counts[1]} + plain = compute(person, month, annual) + excluded = compute(frozen, month, annual) + for year in plain.qcs_by_year: + assert excluded.qcs_by_year[year][0] <= plain.qcs_by_year[year][0] + assert excluded.qcs_by_year[year][1] <= plain.qcs_by_year[year][1] + unavailable = set(range(qid(start_year, 3), qid(start_year + 1, 3))) + assert unavailable.isdisjoint( + quarter + for quarters in excluded.assigned_quarters.values() + for quarter in quarters + ) + + +def test_unknown_upper_bound_respects_exit_quarter(): + person = i.Person(date(2000, 2, 2)) + exit_month = date(2026, 4, 1) + years = history(person, exit_month, {2024: 4, 2025: 4}) + years[2026] = declared(provenance=i.EarningsProvenance.UNKNOWN) + result = i.insured_status( + person, + years, + date(2027, 1, 1), + coverage_end_month=exit_month, + test=i.InsuredTest.FULLY, + ) + assert result.qcs_by_year[2026] == (0, 2) + assert result.fully.insured + + +def test_special_insured_quarter_before_31_boundary(): + person = i.Person(date(1995, 11, 15)) + counts = {2018: 4, 2019: 4, 2020: 4, 2021: 4, 2022: 3} + before = compute(person, date(2026, 7, 1), counts) + attainment_quarter = compute(person, date(2026, 10, 1), counts) + assert before.disability.required == 19 + assert before.disability.insured + assert attainment_quarter.disability.required == 20 + assert not attainment_quarter.disability.insured + + +def test_joseph_subsequent_poms_140_example_6_endpoint_erratum(): + person = i.Person( + date(1956, 9, 16), + disability_onset=date(1984, 2, 14), + prior_disability_periods=( + i.DisabilityPeriod( + date(1981, 2, 3), date(1982, 12, 31), special_insured=True + ), + ), + ) + result = compute( + person, + date(1984, 2, 1), + {1978: 2, 1979: 3, 1980: 4, 1981: 1, 1982: 2, 1983: 4, 1984: 1}, + ) + assert result.disability.insured + # The capture says 18 elapsed / 9 needed. Under .240 and 404.130(f), + # its credited first/last quarters remain: 26 total - 6 interior =20. + source_elapsed, source_required = 18, 9 + assert len(result.disability.window) == source_elapsed + 2 == 20 + assert result.disability.required == source_required + 1 == 10 + assert result.disability.qc_count_lower == 16 + + +@pytest.mark.parametrize( + "birth,onset,start,end,counts,required,window_length", + [ + ( + date(1967, 3, 16), + date(1990, 12, 3), + date(1988, 3, 29), + date(1990, 10, 31), + {1986: 3, 1987: 3}, + 6, + 12, + ), + ( + date(1967, 4, 12), + date(1997, 3, 16), + date(1988, 2, 16), + date(1990, 12, 31), + {1986: 1, 1987: 4, 1988: 1, 1993: 2, 1994: 3, 1995: 4, 1996: 3}, + 12, + 25, + ), + ], + ids=["jane-example-7", "ralph-example-8"], +) +def test_subsequent_under31_poms_140_examples_7_and_8( + birth, onset, start, end, counts, required, window_length +): + person = i.Person( + birth, + disability_onset=onset, + prior_disability_periods=( + i.DisabilityPeriod(start, end, special_insured=True), + ), + ) + result = compute(person, onset.replace(day=1), counts) + assert result.disability.insured + assert result.disability.required == required + assert result.disability.qc_count_lower == required + assert len(result.disability.window) == window_length + + +def test_sam_subsequent_poms_140_example_9_favorable_disregard_erratum(): + person = i.Person( + date(1964, 2, 16), + disability_onset=date(1993, 5, 16), + prior_disability_periods=( + i.DisabilityPeriod( + date(1985, 12, 16), date(1989, 12, 31), special_insured=True + ), + ), + ) + counts = {1983: 2, 1984: 4, 1988: 4, 1989: 4, 1992: 4, 1993: 4} + result = compute(person, date(1993, 5, 1), counts) + # Source says 17 elapsed / 8 needed / 7 available after exclusion. + # CFR404.130(f) requires favorable disregard of the entire period. + source_elapsed, source_required, source_qcs = 17, 8, 7 + assert source_qcs < source_required == source_elapsed // 2 + assert result.disability.insured + assert result.disability.rule == "disability_20_of_40" + assert result.disability.required == result.disability.qc_count_lower == 20 + assert tuple( + q for q in result.disability.assigned_quarters if q // 4 == 1983 + ) == (qid(1983, 3), qid(1983, 4)) + # Disregarding all periods produces the identical qualifying witness. + ignored = compute( + replace(person, prior_disability_periods=()), date(1993, 5, 1), counts + ) + assert ignored.disability.insured + assert ignored.disability.qc_count_lower == 20 + + +@settings(max_examples=12, deadline=None) +@given(st.integers(1978, 1982), st.integers(0, 4)) +def test_property_subsequent_special_and_dli_monotonic(year, count): + person = i.Person( + date(1950, 4, 16), + prior_disability_periods=( + i.DisabilityPeriod( + date(1975, 5, 16), date(1978, 12, 31), special_insured=True + ), + ), + ) + month = date(1983, 6, 1) + lower = { + 1970: 1, + 1971: 2, + 1972: 3, + 1973: 2, + 1974: 2, + 1978: 4, + 1979: 1, + 1980: 1, + 1981: 1, + 1982: 3, + } + lower[year] = count + upper = dict(lower) + upper[year] = min(4, count + 1) + a = compute(person, month, lower) + b = compute(person, month, upper) + assert all( + not old or new + for old, new in zip(statuses(a), statuses(b), strict=True) + ) + assert (b.dli.lower or date.min) >= (a.dli.lower or date.min) + assert a.disability.rule in {"subsequent_special", "disability_20_of_40"} + assert b.disability.rule in {"subsequent_special", "disability_20_of_40"} + + +@pytest.mark.parametrize("count,expected", [(5, False), (6, True)]) +def test_currently_six_qcs_boundary(count, expected): + person = i.Person(date(1990, 2, 2)) + result = compute( + person, + date(2026, 12, 1), + {2025: 4, 2026: count - 4}, + test=i.InsuredTest.CURRENTLY, + ) + assert result.currently.required == 6 + assert result.currently.insured is expected + + +@pytest.mark.parametrize("count,expected", [(19, False), (20, True)]) +def test_disability_twenty_qcs_boundary(count, expected): + person = i.Person(date(1990, 2, 2)) + counts = {2021: 4, 2022: 4, 2023: 4, 2024: 4, 2025: count - 16} + result = compute(person, date(2026, 12, 1), counts) + assert result.fully.insured + assert result.disability.required == 20 + assert result.disability.insured is expected + + +@pytest.mark.parametrize("count,expected", [(5, False), (6, True)]) +def test_fully_six_qcs_minimum(count, expected): + person = i.Person(date(2000, 2, 2)) + result = compute( + person, + date(2026, 12, 1), + {2025: 4, 2026: count - 4}, + test=i.InsuredTest.FULLY, + ) + assert result.fully.required == 6 + assert result.fully.insured is expected + + +def test_guinness_lis_poms_120_freeze_protects_onset_status(): + # The capture supplies insured status at onset, not a DOB/full record. + # This invented completion realizes its declared 20-QC premise. + person = i.Person(date(1940, 2, 2), disability_onset=date(1977, 12, 15)) + counts = {year: 4 for year in range(1973, 1978)} + onset = compute(person, date(1977, 12, 1), counts) + waiting = compute(person, date(1987, 2, 1), counts) + assert onset.disability.insured + assert waiting.disability.insured + assert ( + onset.disability.qc_count_lower + == waiting.disability.qc_count_lower + == 20 + ) + assert onset.disability.window == waiting.disability.window + assert onset.disability.window[-1] == qid(1977, 4) + + +@pytest.mark.parametrize( + "birth,onset,start,end,patterns,insured,required,available,elapsed", + [ + ( + date(1950, 4, 16), + date(1982, 11, 2), + date(1975, 5, 16), + date(1978, 12, 31), + { + 1970: "NNNC", + 1971: "NNCC", + 1972: "CCCN", + 1973: "CNNC", + 1974: "NNCC", + 1976: "CNNN", + 1978: "CCCC", + 1979: "CNNN", + 1980: "CNNN", + 1981: "CNNN", + 1982: "CCCN", + }, + True, + 16, + 16, + 32, + ), + ( + date(1940, 7, 16), + date(1983, 2, 11), + date(1968, 3, 4), + date(1981, 6, 30), + { + 1961: "NNNC", + 1962: "NCCN", + 1963: "NNCC", + 1964: "CCNC", + 1966: "CCNN", + 1967: "CNCC", + 1970: "NNCC", + 1977: "NNNC", + 1980: "CCCC", + 1981: "CCCC", + 1982: "CCNN", + }, + True, + 16, + 18, + 33, + ), + ( + date(1945, 7, 14), + date(1983, 2, 11), + date(1970, 12, 13), + date(1978, 11, 30), + { + 1967: "CNCN", + 1968: "NNCC", + 1969: "NNNC", + 1970: "CCCN", + 1976: "NCCN", + 1978: "CNNN", + }, + False, + 17, + 9, + 34, + ), + ], + ids=[ + "mary-brown-example-1", + "john-jones-example-2", + "frank-smith-example-3-moveable-qc-erratum", + ], +) +def test_subsequent_over31_poms_147_examples( + birth, onset, start, end, patterns, insured, required, available, elapsed +): + person = i.Person( + birth, + disability_onset=onset, + prior_disability_periods=( + i.DisabilityPeriod(start, end, special_insured=True), + ), + ) + years = history(person, date(1983, 6, 1)) + for year, pattern in patterns.items(): + values = ( + {"qc_quarters": tuple(letter == "C" for letter in pattern)} + if year < 1978 + else {"qc_count": pattern.count("C")} + ) + years[year] = i.CoverageYear(i.EarningsProvenance.OBSERVED, **values) + result = i.insured_status(person, years, date(1983, 6, 1)) + assert result.disability.insured is insured + assert result.disability.required == required + assert result.disability.qc_count_lower == available + assert len(result.disability.window) == elapsed + assert result.disability.rule == "subsequent_special" + if birth == date(1945, 7, 14): + # Source freezes 1978 CNNN in Q1. .230 permits moving it to Q4, + # the last PPD quarter; .240 then retains it in both counts. + source_elapsed, source_required, source_available = 33, 16, 8 + assert elapsed == source_elapsed + 1 + assert required == source_required + 1 + assert available == source_available + 1 + assert qid(1978, 4) in result.disability.assigned_quarters + + +def test_sam_favorable_disregard_counterexample_one_qc_boundary(): + person = i.Person( + date(1964, 2, 16), + disability_onset=date(1993, 5, 16), + prior_disability_periods=( + i.DisabilityPeriod( + date(1985, 12, 16), date(1989, 12, 31), special_insured=True + ), + ), + ) + counts = {1983: 1, 1984: 4, 1988: 4, 1989: 4, 1992: 4, 1993: 2} + below = compute(person, date(1993, 5, 1), counts) + counts[1983] = 2 + at = compute(person, date(1993, 5, 1), counts) + assert not below.disability.insured + assert at.disability.insured + assert at.disability.qc_count_lower == 20 + + +def test_dli_fra_cap_poms_148_november_2019(): + # The source specifies FRA11/2019, not a birth date or earnings record. + # This invented completion has at least40QCs before that FRA quarter. + person = i.Person(date(1953, 11, 2)) + result = compute( + person, date(2019, 12, 1), {year: 4 for year in range(2009, 2020)} + ) + assert result.dli.lower == result.dli.upper == date(2019, 9, 30) + assert not result.dli.right_censored + + +def test_age_attainment_day_before_birthday_cfr_404_102_example(): + assert i._attain(date(1917, 7, 1), 62) == date(1979, 6, 30) diff --git a/tests/test_track_b_insured_status_contract.py b/tests/test_track_b_insured_status_contract.py new file mode 100644 index 000000000..94cf87729 --- /dev/null +++ b/tests/test_track_b_insured_status_contract.py @@ -0,0 +1,304 @@ +"""Statutory conformance: event timing and explicit refusal boundaries. + +Invented declarations only; no population, behavioral, or forecast claim. +""" + +from dataclasses import replace +from datetime import date +from fractions import Fraction + +import pytest +from hypothesis import given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as i +from populace_dynamics.track_b.gross_benefits import ( + InvalidFamilyInput, + count_family_outcomes, +) +from tests.test_track_b_insured_status import declared, history + + +def test_future_exit_does_not_remove_dli_censoring(): + person = i.Person(date(1980, 1, 2)) + month = date(2026, 1, 1) + years = history(person, month, {y: 4 for y in range(2015, 2025)}) + result = i.insured_status(person, years, month) + future = i.insured_status( + person, years, month, coverage_end_month=date(2027, 12, 1) + ) + assert result == future + assert future.dli.right_censored + + +def test_currently_insured_uses_death_quarter_after_death(): + person = i.Person(date(1980, 1, 2), death_date=date(2020, 12, 15)) + years = history(person, date(2020, 12, 1), {2019: 4, 2020: 4}) + at_death = i.insured_status(person, years, date(2020, 12, 1)) + later = i.insured_status(person, years, date(2026, 1, 1)) + assert at_death.currently == later.currently + assert later.currently.insured + assert later.currently.window[-1] == 2020 * 4 + 3 + + +@pytest.mark.parametrize( + "field", ["rib_entitlement_month", "dib_entitlement_month"] +) +def test_currently_insured_preserves_actual_entitlement_event(field): + person = i.Person(date(1960, 1, 2), **{field: date(2020, 12, 1)}) + month = date(2026, 1, 1) + years = history(person, month, {2019: 4, 2020: 4}) + actual = i.insured_status(person, years, month) + hypothetical = i.insured_status( + replace(person, **{field: None}), years, month + ) + assert actual.currently.insured + assert not hypothetical.currently.insured + + +def test_currently_insured_accepts_any_statutory_event(): + person = i.Person( + date(1960, 1, 2), + dib_entitlement_month=date(2000, 12, 1), + rib_entitlement_month=date(2022, 12, 1), + death_date=date(2025, 12, 10), + ) + month = date(2026, 1, 1) + years = history(person, month, {1999: 4, 2000: 4}) + result = i.insured_status(person, years, month) + assert result.currently.insured + assert result.currently.window[-1] == 2000 * 4 + 3 + + # RS00301.110 excludes prior periods, not the period containing the + # historical entitlement event itself. Its later end is known here. + person = i.Person( + date(1960, 2, 2), + dib_entitlement_month=date(2000, 7, 1), + prior_disability_periods=( + i.DisabilityPeriod(date(2000, 1, 1), date(2005, 12, 31)), + ), + ) + month = date(2010, 1, 1) + years = history( + person, month, {1991: 4, 1992: 4, 1993: 4, 1994: 4, 1997: 4, 1998: 2} + ) + result = i.insured_status( + person, years, month, test=i.InsuredTest.CURRENTLY + ) + assert not result.currently.insured + assert result.currently.qc_count_lower == 4 + + +@pytest.mark.parametrize("condition", list(i.CoverageCondition)) +def test_each_declared_specialist_condition_has_named_retained_refusal( + condition, +): + person = i.Person(date(1980, 2, 2), conditions=(condition,)) + month = date(2026, 1, 1) + years = history(person, month) + row = i.evaluate_insured_status( + condition.value, + Fraction(2), + lambda: i.insured_status(person, years, month), + ) + assert row.unsupported.reason is i.InsuredUnsupportedReason[condition.name] + count = count_family_outcomes((row,)) + assert count.rows == count.unsupported_rows == 1 + assert count.unsupported_weight == 2 + del years[2000] + with pytest.raises(InvalidFamilyInput): + i.evaluate_insured_status( + condition.value, + Fraction(2), + lambda: i.insured_status(person, years, month), + ) + + +def test_alien_sspa_requirement_has_explicit_trigger(): + month = date(2026, 1, 1) + early = i.Person( + date(1980, 2, 2), + alien_worker=True, + ssn_assignment_date=date(2003, 12, 31), + ) + late = replace(early, ssn_assignment_date=date(2004, 1, 1)) + years = history(early, month) + assert not i.insured_status(early, years, month).fully.insured + with pytest.raises(i.InsuredConfigurationUnsupported) as error: + i.insured_status(late, years, month) + assert error.value.reason is i.InsuredUnsupportedReason.ALIEN_WORKER + with pytest.raises(InvalidFamilyInput): + replace(early, ssn_assignment_date=date(1979, 1, 1)) + + +@pytest.mark.parametrize( + "year,values,reason", + [ + ( + 1937, + {"quarterly_wages": (50, 0, 0, 0)}, + i.InsuredUnsupportedReason.EARNINGS_1937, + ), + ( + 1950, + {"self_employment": 400}, + i.InsuredUnsupportedReason.PRE1951_SELF_EMPLOYMENT, + ), + ( + 1954, + {"agricultural_wages": 100}, + i.InsuredUnsupportedReason.PRE1955_AGRICULTURE, + ), + (2028, {"wages": 10000}, i.InsuredUnsupportedReason.QC_YEAR), + ], +) +def test_raw_earnings_refusals_are_own_layer(year, values, reason): + person = i.Person(date(1914, 2, 2)) + month = date(2028, 1, 1) + years = history(person, month) + years[year] = i.CoverageYear(i.EarningsProvenance.OBSERVED, **values) + with pytest.raises(i.InsuredConfigurationUnsupported) as error: + i.insured_status(person, years, month) + assert error.value.reason is reason + + +def test_input_calendar_errors_precede_totalization_refusal(): + person = i.Person(date(1950, 8, 2)) + month = date(1970, 12, 1) + years = history(person, month) + years[1950] = i.CoverageYear( + i.EarningsProvenance.OBSERVED, qc_quarters=(True, False, False, False) + ) + with pytest.raises(InvalidFamilyInput): + i.insured_status(person, years, month, totalization_credits=("UK",)) + years = history(person, month) + with pytest.raises(InvalidFamilyInput): + i.insured_status( + replace(person, disability_onset=date(1971, 1, 1)), years, month + ) + with pytest.raises(InvalidFamilyInput): + i.insured_status( + replace(person, rib_entitlement_month=date(1971, 1, 1)), + years, + month, + ) + + +@settings(max_examples=15, deadline=None) +@given(st.integers(1, 4), st.integers(0, 4)) +def test_unknown_birth_and_exit_year_cap_is_sound(quarter, count): + person = i.Person(date(2000, 2, 2)) + month = date(2026, quarter * 3, 1) + years = history(person, month, {2024: 4, 2025: 4}) + years[2026] = i.CoverageYear(i.EarningsProvenance.UNKNOWN) + result = i.insured_status( + person, + years, + month, + test=i.InsuredTest.FULLY, + coverage_end_month=month, + ) + assert result.qcs_by_year[2026] == (0, quarter) + years[2026] = declared(count) + concrete = i.insured_status( + person, + years, + month, + test=i.InsuredTest.FULLY, + coverage_end_month=month, + ) + assert concrete.fully.insured == result.fully.insured + assert ( + result.fully.qc_count_lower + <= concrete.fully.qc_count_lower + <= result.fully.qc_count_upper + ) + + +def test_dli_unknown_year_is_a_range_not_an_undocumented_point(): + person = i.Person(date(1980, 2, 2)) + month = date(2026, 12, 1) + years = history(person, month, {y: 4 for y in range(2000, 2005)}) + years[2005] = i.CoverageYear(i.EarningsProvenance.UNKNOWN) + result = i.insured_status( + person, years, month, test=i.InsuredTest.DISABILITY + ) + assert not result.disability.insured + assert result.dli.lower == date(2009, 12, 31) + assert result.dli.upper == date(2010, 12, 31) + for count in range(5): + concrete = dict(years) + concrete[2005] = declared(count) + value = i.insured_status( + person, concrete, month, test=i.InsuredTest.DISABILITY + ) + assert result.dli.lower <= value.dli.lower <= result.dli.upper + + +def test_pre1911_male_dib_fully_requirement_uses_1975_cap_cfr_404_132(): + person = i.Person(date(1900, 2, 2), sex=i.Sex.MALE) + month = date(1974, 12, 1) + years = history(person, month, {year: 4 for year in range(1969, 1974)}) + result = i.insured_status(person, years, month) + assert result.fully.required == 14 + assert result.fully.insured + assert result.disability.qc_count_lower == 20 + assert not result.disability.insured # DIB fully test needs23, not14. + + +def test_requirement_helper_rejects_future_prior_period_and_onset(): + person = i.Person(date(1980, 2, 2)) + month = date(2020, 1, 1) + for changed in ( + replace(person, disability_onset=date(2021, 1, 1)), + replace( + person, + prior_disability_periods=( + i.DisabilityPeriod(date(2020, 1, 1), date(2020, 12, 1)), + ), + ), + ): + with pytest.raises(InvalidFamilyInput): + i.fully_insured_requirement(changed, month) + + +@settings(max_examples=10, deadline=None) +@given(st.lists(st.integers(0, 4), min_size=8, max_size=8)) +def test_unknown_bounds_with_prior_disability_period(counts): + person = i.Person( + date(1980, 2, 2), + prior_disability_periods=( + i.DisabilityPeriod( + date(2004, 4, 15), date(2006, 9, 15), special_insured=True + ), + ), + ) + month = date(2012, 12, 1) + years = history( + person, month, dict(zip(range(2005, 2013), counts, strict=True)) + ) + years[2006] = i.CoverageYear(i.EarningsProvenance.UNKNOWN) + for kind in ( + i.InsuredTest.FULLY, + i.InsuredTest.CURRENTLY, + i.InsuredTest.DISABILITY, + ): + try: + result = i.insured_status(person, years, month, test=kind) + except i.InsuredConfigurationUnsupported as refusal: + assert ( + refusal.reason is i.InsuredUnsupportedReason.UNKNOWN_EARNINGS + ) + continue + for count in range(5): + concrete = dict(years) + concrete[2006] = declared(count) + value = i.insured_status(person, concrete, month, test=kind) + assert ( + getattr(value, kind.value).insured + == getattr(result, kind.value).insured + ) + if result.dli is not None: + lower = result.dli.lower or date.min + upper = result.dli.upper or date.min + assert lower <= (value.dli.lower or date.min) <= upper diff --git a/tests/test_track_b_insured_status_qc.py b/tests/test_track_b_insured_status_qc.py new file mode 100644 index 000000000..9f9c7e7a3 --- /dev/null +++ b/tests/test_track_b_insured_status_qc.py @@ -0,0 +1,411 @@ +"""QC statutory conformance on invented and published cases; no real data. + +Source quotations and capture hashes are checked by the insured-status +source tests. These tests execute the covered-earnings and assignment rules +independently of the public declaration/seal/status boundary. +""" + +from datetime import date +from fractions import Fraction as F +from itertools import permutations + +import pytest +from hypothesis import given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import _insured_status_qc as qc + + +def _quarters(year, *numbers): + return tuple(qc._quarter_id(year, value) for value in numbers) + + +@settings(deadline=None) +@given( + year=st.integers(1978, 2027), + wages=st.integers(0, 10000000), + sei=st.integers(0, 10000000), + additional=st.integers(0, 10000000), +) +def test_qcs_bounded_and_monotone_in_earnings(year, wages, sei, additional): + count = qc._post1977_qc_count(year, F(wages, 100), F(sei, 100)) + raised = qc._post1977_qc_count( + year, F(wages + additional, 100), F(sei, 100) + ) + assert 0 <= count <= raised <= 4 + + +@pytest.mark.parametrize("year", range(1978, 2028)) +@pytest.mark.parametrize("multiple", range(1, 5)) +def test_published_increment_exact_boundary(year, multiple): + threshold = qc.QC_AMOUNTS[year] * multiple + assert qc._post1977_qc_count(year, F(threshold) - F(1, 100), F(0)) == ( + multiple - 1 + ) + assert qc._post1977_qc_count(year, F(threshold), F(0)) == multiple + assert qc._post1977_qc_count(year, F(0), F(threshold)) == multiple + + +@pytest.mark.parametrize( + ("delta", "expected"), + [(F(-1, 100), 250), (F(0), 260), (F(1, 100), 260)], +) +def test_qc_amount_ties_round_up(delta, expected): + nawi = (255 + delta) * F("9226.48") / 250 + assert qc._qc_amount_from_nawi(nawi, 250) == expected + + +@settings(deadline=None) +@given( + low=st.integers(1, 100000000), + increase=st.integers(0, 100000000), + prior=st.integers(25, 1000), +) +def test_qc_amount_prior_floor_and_nawi_monotonicity(low, increase, prior): + first = qc._qc_amount_from_nawi(F(low, 100), prior * 10) + second = qc._qc_amount_from_nawi(F(low + increase, 100), prior * 10) + assert prior * 10 <= first <= second + assert first % 10 == second % 10 == 0 + + +def test_oact_2027_published_determination(): + unrounded = 250 * F("72800.33") / F("9226.48") + # OACT displays the intermediate to cents; statute rounds the exact ratio. + assert (unrounded * 100 + F(1, 2)) // 1 == 197259 + assert qc._qc_amount_from_nawi(F("72800.33"), 1890) == 1970 + assert qc.QC_AMOUNTS[2027] == 1970 + + +def test_cfr404_143_two_and_fraction_increments(): + # The CFR's example is symbolic: greater than twice, below three times. + for year, increment in qc.QC_AMOUNTS.items(): + assert qc._post1977_qc_count(year, F(5, 2) * increment, F(0)) == 2 + + +@pytest.mark.parametrize("year", range(1938, 1978)) +def test_pre1978_fifty_dollar_quarter_boundary(year): + fixed, flexible = qc._pre1978_qc_credits( + year, (F("49.99"), F(50), F(0), F("50.01")), F(0), F(0) + ) + assert fixed == _quarters(year, 2, 4) + assert flexible == 0 + + +@pytest.mark.parametrize("year", range(1951, 1978)) +def test_pre1978_calendar_sei_four_hundred_boundary(year): + zeros = (F(0),) * 4 + assert qc._pre1978_qc_credits(year, zeros, F("399.99"), F(0)) == ( + (), + 0, + ) + assert qc._pre1978_qc_credits(year, zeros, F(400), F(0)) == ( + qc._year_quarters(year), + 0, + ) + + +@pytest.mark.parametrize( + ("first", "last", "limit"), + [ + (1937, 1950, 3000), + (1951, 1954, 3600), + (1955, 1958, 4200), + (1959, 1965, 4800), + (1966, 1967, 6600), + (1968, 1971, 7800), + (1972, 1972, 9000), + (1973, 1973, 10800), + (1974, 1974, 13200), + (1975, 1975, 14100), + (1976, 1976, 15300), + (1977, 1977, 16500), + ], +) +def test_maximum_taxable_wages_give_four_gift_qcs(first, last, limit): + for year in range(first, last + 1): + assert qc._annual_wage_limit(year) == limit + if year == 1937: + # The annual wage threshold is captured; raw earnings also + # require Act 213(b)'s half-year/age-65 allocation and refuse. + continue + assert qc._pre1978_qc_credits( + year, (F(limit), F(0), F(0), F(0)), F(0), F(0) + ) == (qc._year_quarters(year), 0) + assert qc._pre1978_qc_credits( + year, (F(limit) - F(1, 100), F(0), F(0), F(0)), F(0), F(0) + ) == (_quarters(year, 1), 0) + + +@settings(deadline=None) +@given( + year=st.integers(1955, 1977), + wages=st.tuples(*(st.integers(0, 100000) for _ in range(4))), + ag=st.integers(0, 100000), + increase=st.integers(0, 100000), +) +def test_pre1978_qcs_bounded_and_monotone(year, wages, ag, increase): + normalized = tuple(F(value, 100) for value in wages) + fixed, flexible = qc._pre1978_qc_credits( + year, normalized, F(0), F(ag, 100) + ) + more_fixed, more_flexible = qc._pre1978_qc_credits( + year, normalized, F(0), F(ag + increase, 100) + ) + assert 0 <= len(fixed) + flexible <= len(more_fixed) + more_flexible <= 4 + + +def test_rs00301_320_jane_agricultural_example(): + # Covered agricultural wages: Brown 101+59, Black150, Green90. + fixed, flexible = qc._pre1978_qc_credits( + 1973, (F(0), F(0), F(50), F(0)), F(0), F(101 + 150 + 90 + 59) + ) + assert fixed == _quarters(1973, 3) + assert flexible == 3 + assert qc._assign_qcs(fixed, flexible, qc._year_quarters(1973)) == ( + qc._year_quarters(1973) + ) + + +@pytest.mark.parametrize("ag_count", range(5)) +def test_agricultural_qcs_fill_quarters_not_already_credited(ag_count): + fixed, flexible = qc._pre1978_qc_credits( + 1973, (F(0), F(0), F(50), F(0)), F(0), F(100 * ag_count) + ) + candidates = qc._assignment_candidates( + fixed, flexible, qc._year_quarters(1973) + ) + assert all(len(value) == min(1 + ag_count, 4) for value in candidates) + assert all(qc._quarter_id(1973, 3) in value for value in candidates) + + +def test_agricultural_assignment_ordinary_latest_and_favorable_exception(): + fixed = _quarters(1973, 3) + allowed = qc._year_quarters(1973) + assert qc._assign_qcs(fixed, 1, allowed) == _quarters(1973, 3, 4) + assert qc._assign_qcs(fixed, 1, allowed, _quarters(1973, 1)) == ( + _quarters(1973, 1, 3) + ) + + +def test_rs00301_230_henry_and_325_john_retroactive_assignment(): + # Both published 2010 examples require the one annual QC in Q1. + for wages in (F(1500), F(1200)): + count = qc._post1977_qc_count(2010, wages, F(0)) + assert count == 1 + assert qc._assign_qcs( + (), count, qc._year_quarters(2010), _quarters(2010, 1) + ) == _quarters(2010, 1) + + +@settings(deadline=None) +@given( + fixed_flags=st.tuples(*(st.booleans() for _ in range(4))), + permitted_flags=st.tuples(*(st.booleans() for _ in range(4))), + target_flags=st.tuples(*(st.booleans() for _ in range(4))), + flexible=st.integers(0, 4), +) +def test_assignment_maximizes_window_and_is_order_independent( + fixed_flags, permitted_flags, target_flags, flexible +): + quarters = qc._year_quarters(2000) + fixed = tuple( + q for q, flag in zip(quarters, fixed_flags, strict=True) if flag + ) + allowed = tuple( + q for q, flag in zip(quarters, permitted_flags, strict=True) if flag + ) + window = tuple( + q for q, flag in zip(quarters, target_flags, strict=True) if flag + ) + actual = qc._assign_qcs(fixed, flexible, allowed, window) + candidates = qc._assignment_candidates(fixed, flexible, allowed) + assert len(actual) <= 4 + assert len(actual) == len(set(actual)) + assert set(actual) <= set(allowed) + assert set(fixed) & set(allowed) <= set(actual) + assert len(set(actual) & set(window)) == max( + len(set(candidate) & set(window)) for candidate in candidates + ) + assert actual == qc._assign_qcs( + tuple(reversed(fixed)), + flexible, + tuple(reversed(allowed)), + tuple(reversed(window)), + ) + assert actual == qc._assign_qcs(fixed, flexible, allowed, window) + + +def test_assignment_all_six_two_credit_combinations_are_reachable(): + candidates = qc._assignment_candidates((), 2, qc._year_quarters(2020)) + assert len(candidates) == 6 + for target in candidates: + assert qc._assign_qcs((), 2, qc._year_quarters(2020), target) == target + for permuted in permutations(qc._year_quarters(2020)): + assert qc._assignment_candidates((), 2, permuted) == candidates + + +@settings(deadline=None) +@given( + year=st.integers(1937, 2027), + start=st.integers(0, 3), + length=st.integers(0, 6), + count=st.integers(0, 4), +) +def test_disability_exclusion_never_adds_qc(year, start, length, count): + quarters = qc._year_quarters(year) + first = quarters[start] + end = first + length + allowed = qc._allowed_quarters( + year, + through_quarter=quarters[-1], + disability_periods=((first, end),), + ) + assert set(allowed) <= set(quarters) + assert first in allowed + if end in quarters: + assert end in allowed + assert all(not first < value < end for value in allowed) + assert len(qc._assign_qcs((), count, allowed)) <= len( + qc._assign_qcs((), count, quarters) + ) + + +def test_death_future_exit_and_disability_endpoint_exclusions(): + quarters = qc._year_quarters(2026) + assert ( + qc._allowed_quarters( + 2026, + through_quarter=quarters[2], + death_quarter=quarters[1], + coverage_end_quarter=quarters[3], + ) + == quarters[:2] + ) + assert ( + qc._allowed_quarters( + 2026, through_quarter=quarters[3], coverage_end_quarter=quarters[0] + ) + == quarters[:1] + ) + assert qc._allowed_quarters( + 2026, + through_quarter=quarters[3], + disability_periods=((quarters[0], quarters[3]),), + ) == (quarters[0], quarters[3]) + # A disallowed fixed wage quarter does not migrate to another quarter. + assert qc._assign_qcs(quarters[1:2], 0, (quarters[0], quarters[3])) == () + + +def test_rs00301_220_ann_calendar_year_sei_allocation(): + assert qc._allocate_sei_post1977( + date(1987, 10, 1), date(1988, 9, 30), F(12000) + ) == ((1987, F(3000)), (1988, F(9000))) + + +def test_cfr404_144_partial_month_taxable_year_example(): + assert qc._allocate_sei_post1977( + date(1978, 5, 15), date(1979, 5, 14), F(1200) + ) == ((1978, F(700)), (1979, F(500))) + + +def test_rs00301_340_john_fiscal_sei_allocation(): + assert qc._allocate_sei_pre1978( + date(1973, 4, 1), date(1974, 3, 31), F(10800) + ) == tuple( + (quarter, F(2700)) + for quarter in (*_quarters(1973, 2, 3, 4), *_quarters(1974, 1)) + ) + + +def test_rs00301_340_short_year_source_erratum_is_not_imitated(): + actual = qc._allocate_sei_pre1978( + date(1973, 9, 1), date(1974, 1, 3), F(10900) + ) + assert actual == tuple( + (quarter, F(10900, 3)) + for quarter in (*_quarters(1973, 3, 4), *_quarters(1974, 1)) + ) + assert sum(amount for _, amount in actual) == 10900 + # POMS labels $10,900 as SEI but prints $3,600 each. Literal equal + # allocation under 404.142 is $10,900/3. An omitted contribution-base + # cap explains the printed figure if $10,900 meant net earnings: + # 213(a)(2)(B)(iii) gives the 1973 taxable year a $10,800 maximum. + assert 3 * F(3600) == 10800 != F(10900) + assert all(amount >= 100 for _, amount in actual) + covered = min(F(10900), F(qc._annual_wage_limit(1973))) + capped = qc._allocate_sei_pre1978( + date(1973, 9, 1), date(1974, 1, 3), covered + ) + assert covered == 10800 + assert all(amount == 3600 for _, amount in capped) + assert len(capped) == len(actual) == 3 + + +@pytest.mark.parametrize( + ("start", "end", "sei", "wages", "expected"), + [ + ( + date(1973, 7, 1), + date(1974, 6, 30), + F(8100), + F(2700), + (*_quarters(1973, 3, 4), *_quarters(1974, 1, 2)), + ), + ( + date(1973, 6, 1), + date(1974, 5, 31), + F(10800), + F(0), + (*_quarters(1973, 2, 3, 4), *_quarters(1974, 1, 2)), + ), + ( + date(1973, 6, 1), + date(1974, 5, 31), + F(10620), + F(180), + (*_quarters(1973, 2, 3, 4), *_quarters(1974, 1, 2)), + ), + ], +) +def test_rs00301_345_fiscal_gift_credit_examples( + start, end, sei, wages, expected +): + assert qc._pre1978_taxable_qcs(start, end, sei, wages) == expected + + +@settings(deadline=None) +@given( + amount=st.integers(40000, 10000000), + start_month=st.integers(1, 12), + duration=st.integers(0, 3), +) +def test_exact_sei_allocation_conserves_income(amount, start_month, duration): + start = date(1973, start_month, 1) + end_month = start_month - 1 + duration + end = date(1973 + end_month // 12, end_month % 12 + 1, 28) + allocations = qc._allocate_sei_pre1978(start, end, F(amount, 100)) + assert sum(value for _, value in allocations) == F(amount, 100) + assert 1 <= len(allocations) <= 4 + assert len({value for _, value in allocations}) == 1 + post = qc._allocate_sei_post1977(start, end, F(amount, 100)) + assert sum(value for _, value in post) == F(amount, 100) + + +@pytest.mark.parametrize( + ("year", "sei", "ag", "reason"), + [ + (1954, F(0), F(100), "pre1955_agricultural_allocation_unsupported"), + (1950, F(400), F(0), "pre1951_self_employment_unsupported"), + ], +) +def test_precoverage_earnings_need_explicit_resolution(year, sei, ag, reason): + with pytest.raises(qc._UnsupportedQC) as error: + qc._pre1978_qc_credits(year, (F(0),) * 4, sei, ag) + assert error.value.reason == reason + + +def test_1937_raw_earnings_refuse_but_zero_does_not_need_allocation(): + with pytest.raises(qc._UnsupportedQC) as error: + qc._pre1978_qc_credits(1937, (F(50), F(0), F(0), F(0)), F(0), F(0)) + assert error.value.reason == "1937_earnings_allocation_unsupported" + assert qc._pre1978_qc_credits(1937, (F(0),) * 4, F(0), F(0)) == ((), 0) diff --git a/tests/test_track_b_insured_status_sources.py b/tests/test_track_b_insured_status_sources.py new file mode 100644 index 000000000..d743c00e8 --- /dev/null +++ b/tests/test_track_b_insured_status_sources.py @@ -0,0 +1,531 @@ +"""Statutory conformance: captured insured-status rules and source tables. + +Published examples and invented cases only; no population, behavioral or +forecast claim. Missing linked POMS exhibits are recorded explicitly and +are not represented as captured charts. +""" + +from __future__ import annotations + +import ast +import hashlib +import html +import json +import re +import xml.etree.ElementTree as ET +from datetime import date, datetime +from decimal import Decimal +from fractions import Fraction +from functools import cache +from pathlib import Path + +import pytest +import yaml + +DATA = Path(__file__).with_name("data") / "track_b" +SOURCES = DATA / "insured_status_sources" + + +@cache +def manifest(): + return json.loads((SOURCES / "manifest.json").read_text()) + + +@cache +def registry(): + return yaml.safe_load((DATA / "insured_status_examples.yaml").read_text()) + + +@cache +def source_text(source_id): + source = next(s for s in manifest()["sources"] if s["id"] == source_id) + text = (SOURCES / source["file"]).read_text() + if source["file"].endswith((".html", ".xml")): + text = re.sub(r"(?is)<(script|style)[^>]*>.*?", " ", text) + text = html.unescape(re.sub(r"<[^>]+>", " ", text)) + text = text.replace("\u200b", " ").replace("’", "'") + return " ".join(text.split()) + + +# Each retained capture has a specific rule or documentary-purpose quote. +# The two exhibit shells are retained to pin exactly what is unavailable. +RULE_QUOTES = { + "poms_rs_00301_000_toc": [ + "Retirement, Survivors and Disability Requirements", + "RS 00301.800 Quarters of Coverage Requirements - Exhibit", + ], + "poms_rs_00301_101": [ + "For certain benefits, the QCs must be earned within a specific " + "time frame.", + ], + "poms_rs_00301_102": [ + "Section 211 of the SSPA applies to an alien worker whose Social " + "Security Number (SSN) was first assigned on or after January 1, " + "2004.", + ], + "poms_rs_00301_105": [ + "A NH needs at least 6 QCs and no more than 40 QCs to meet fully " + "insured status.", + "In determining the number of years, do not count any year if " + "part or all of that year is included in a period of disability " + "if entitlement or a higher benefit would result.", + ], + "poms_rs_00301_106": [ + "Do not use QCs earned before 01/01/84 for deemed fully insured " + "status.", + ], + "poms_rs_00301_107": [ + "Contact the employer to establish that deemed fully insured " + "status does exist.", + ], + "poms_rs_00301_110": [ + "The 13-quarter period ending with the quarter of death;", + "An intervening period of disability may extend the 13-quarter " + "period during which the six QC's necessary for a currently " + "insured status must be acquired.", + ], + "poms_rs_00301_120": [ + "Have at least 20 QC's during a 40 quarter period ending with " + "the quarter the waiting period begins;", + "When there are two or more prior periods of disability, either " + "all must be disregarded or all must be used when determining " + "insured status and benefit amount.", + ], + "poms_rs_00301_122": [ + "Cash benefits are not payable.", + ], + "poms_rs_00301_130": [ + "Have at least 20 QC's in a period of 40 consecutive calendar " + "quarters ending with that quarter;", + ], + "poms_rs_00301_131": [ + "For freeze-insured status, include quarters of coverage based " + "on certain RR compensation or MS credits that are not " + "creditable for other Retirement, Survivors, and Disability " + "Insurance purposes.", + ], + "poms_rs_00301_132": [ + "Do not use a freeze period if it would cause a denial of or " + "reduced benefits.", + ], + "poms_rs_00301_140": [ + "Are under a disability which began before the quarter in which " + "they attained or would attain age 31;", + "If the number of elapsed quarters after age 21 is an odd " + "number, subtract one elapsed quarter from the total elapsed " + "quarters.", + ], + "poms_rs_00301_147": [ + "Had a prior period of disability (PPD) established before age " + "31 and met only the special insured status requirements;", + ], + "poms_rs_00301_148": [ + "DLI is the last day in the last quarter when disability " + "insured status is met.", + "If full retirement age (FRA) attainment is involved, the DLI " + "is the last day of the quarter before the quarter of FRA " + "attainment.", + ], + "poms_rs_00301_149": [ + "See OS 15020.220 for SSA-1164, Worksheet – Special Insured Status", + ], + "poms_rs_00301_150": [ + "For benefits payable January 1973 or later, a statutorily " + "blind worker no longer needs to meet a 20/40 or special insured " + "status test.", + ], + "poms_rs_00301_160": [ + "Meeting the requirements for a freeze only is not sufficient " + "to qualify for Medicare.", + ], + "poms_rs_00301_161": [ + "The reduction is effective 01/94 or, if later, the month after " + "the month an individual receives the 30th QC.", + ], + "poms_rs_00301_200": [ + "For 1978, the law specifically set the increment amount at $250.", + ], + "poms_rs_00301_210": [ + "Credit a QC (maximum of 4) for each increment of total earnings " + "credited to the year.", + ], + "poms_rs_00301_220": [ + "the number of months in each calendar year that are completely " + "included within the taxable year.", + ], + "poms_rs_00301_230": [ + "Assignment of QCs is flexible.", + "We determine QCs by the amount of earnings credited to a " + "calendar year and assign them to the quarters most " + "advantageous to the NH.", + ], + "poms_rs_00301_240": [ + "Do not count a quarter as more than one QC.", + "Except for the first and last such quarters, any quarter of " + "which any portion is included in a period of disability " + "cannot be a QC.", + "A future quarter is a quarter that has not yet commenced " + "and; therefore, cannot be a QC.", + ], + "poms_rs_00301_250": [ + "The following chart contains increment amounts for the years " + "shown.", + ], + "poms_rs_00301_301": [ + "SSA credits QCs on wages paid to an individual after 1936, " + "or on SEI for taxable years beginning after 1950.", + ], + "poms_rs_00301_310": [ + "If the NH had more than one employer, it is only necessary " + "that the total wages from all employers is $50 or more.", + ], + "poms_rs_00301_315": [ + "The simplified method does not apply to disability claims.", + ], + "poms_rs_00301_320": [ + "$400 or more paid in a calendar year-all four quarters are QCs;", + ], + "poms_rs_00301_325": [ + "We credit agricultural labor QCs in 1951 through 1954 as " + "regular wage QCs.", + ], + "poms_rs_00301_340": [ + "We credit SEI equally to each quarter of the calendar year.", + ], + "poms_rs_00301_345": [ + "If a number holder (NH) has maximum creditable earnings in a " + "year, all quarters in that year are QCs.", + "$10,800 in a TY beginning after 1972 and before 1974;", + ], + "poms_rs_00301_350": [ + "The Railroad Retirement Act contains a table for computing " + "compensation for QCs before 1978.", + ], + "poms_rs_00301_470": [ + "a WWII veteran who separated from active military service " + "before July 27, 1951, and died within three years after such " + "separation to have died fully insured.", + ], + "poms_rs_00301_475": [ + "Any wages reallocated based on wages earned cannot then be " + "used to establish a QC based on wages paid for the same year " + "or any subsequent year.", + ], + "poms_rs_00301_480": [ + "It is also not effective for disabilities beginning after " + "1955, as any NH disabled after 1955 and meeting the " + "alternative test would be insured under the 20/40 rule.", + ], + "poms_rs_00301_600": [ + "The election of coverage by a religious order under the " + "“vow-of-poverty provision” may give a member of the order " + "insured status.", + ], + "poms_rs_00301_800": [ + "Quarters of Coverage Requirements (Back) - Exhibit", + ], + "ecfr_20cfr404_subpart_b": [ + "You reach a particular age on the day before your birthday.", + "You are fully insured as of the first day of the calendar " + "quarter in which you acquire the last needed QC", + ], + "lii_usc_42_413": [ + "with such product, if not a multiple of $10, being rounded " + "to the next higher multiple of $10 where such amount is a " + "multiple of $5 but not of $10 and to the nearest multiple " + "of $10 in any other case.", + "$10,800 in the case of a taxable year beginning after 1972 " + "and before 1974", + ], + "lii_usc_42_414": [ + "one quarter of coverage (whenever acquired) for each calendar " + "year elapsing after 1950 (or, if later, the year in which he " + "attained age 21)", + ], + "lii_usc_42_416": [ + "on the first day of the first quarter thereafter in which he " + "satisfies such requirements.", + ], + "lii_usc_42_423": [ + "not less than 20 quarters of coverage during the 40-quarter " + "period which ends with the quarter in which such month occurred", + "when the number of quarters in any period is an odd number, " + "such number shall be reduced by one", + ], + "ssa_oact_qc": [ + "No matter how high your earnings may be, you can not earn " + "more than 4 QC's in one year.", + ], +} + + +def test_manifest_pins_every_capture(): + document = manifest() + assert document["schema_version"] == 1 + sources = document["sources"] + assert len(sources) == 44 + assert len({source["id"] for source in sources}) == len(sources) + for source in sources: + data = (SOURCES / source["file"]).read_bytes() + assert len(data) == source["bytes"], source["id"] + assert hashlib.sha256(data).hexdigest() == source["sha256"] + assert source["url"].startswith("https://") + when = datetime.fromisoformat(source["retrieved_at_utc"]) + assert when.utcoffset().total_seconds() == 0 + assert source["capture"] in document["capture_formats"] + if source["id"].startswith("poms"): + assert re.fullmatch(r"\d{2}/\d{2}/\d{4}", source["page_date"]) + if source["id"] != "poms_rs_00301_000_toc": + assert source["poms_transmittal"].startswith("TN ") + if source["capture"] != "http_body": + assert source["served_bodies"] + for body in source["served_bodies"]: + assert body["url"].startswith("https://") + assert re.fullmatch(r"[0-9a-f]{64}", body["sha256"]) + assert body["bytes"] > len(data) + assert {path.name for path in SOURCES.iterdir()} == { + "manifest.json", + "README.md", + *(source["file"] for source in sources), + } + + +@pytest.mark.parametrize("source_id,quotes", RULE_QUOTES.items()) +def test_rule_text_is_quoted_from_the_captures(source_id, quotes): + text = source_text(source_id) + for quote in quotes: + assert quote in text, (source_id, quote) + + +@pytest.mark.parametrize( + "example", registry()["examples"], ids=lambda e: e["id"] +) +def test_worked_example_figures_are_quoted_from_the_captures(example): + for quote in example["quotes"]: + assert quote in source_text(example["source"]), (example["id"], quote) + + +def test_every_retained_source_has_a_specific_use(): + assert {source["id"] for source in manifest()["sources"]} == set( + RULE_QUOTES + ) + ids = [case["id"] for case in registry()["examples"]] + assert len(ids) == len(set(ids)) + for finding in registry()["source_findings"].values(): + for quote in finding.get("quotes", [finding.get("quote")]): + assert quote in source_text(finding["source"]) + + +def test_registry_computations_name_existing_execution_tests(): + root = DATA.parents[2] + functions_by_path = {} + for example in registry()["examples"]: + if example["coverage"] in { + "computed", + "source_erratum", + "source_ambiguity", + "source_rule_divergence", + "table_differential", + }: + path, name = example["test_node"].split("::") + if path not in functions_by_path: + functions_by_path[path] = { + node.name + for node in ast.walk(ast.parse((root / path).read_text())) + if isinstance(node, ast.FunctionDef) + } + assert name in functions_by_path[path], example["id"] + + +def test_rulespec_dispatch_law_is_copied_from_captures(): + root = DATA.parents[2] + dispatch = ( + root / "docs/design/track_b_insured_status_rulespec_issue.md" + ).read_text() + for number in (413, 414, 423): + source = next( + entry + for entry in manifest()["sources"] + if entry["id"] == f"lii_usc_42_{number}" + ) + for paragraph in ( + (SOURCES / source["file"]).read_text().strip().split("\n\n") + ): + assert "> " + paragraph in dispatch + + +@pytest.mark.parametrize( + "example_id,quote", + [ + ( + "poms_102_2_john", + "The deceased worker was never assigned an SSN.", + ), + ( + "poms_102_5_kismet", + "They have never been assigned an SSN, nor were they ever " + "issued an SSN card for work purposes.", + ), + ( + "poms_102_6_rocky", + "Rocky and Oksana were never assigned SSNs.", + ), + ( + "poms_102_7_cyril", + "nor were they ever assigned an SSN.", + ), + ], +) +def test_poms_102_never_assigned_ssn_is_a_named_refusal(example_id, quote): + from populace_dynamics.track_b import insured_status as i + from populace_dynamics.track_b.gross_benefits import count_family_outcomes + + assert quote in source_text("poms_rs_00301_102") + # Published cases do not give complete year-level records. The invented + # zero history only supplies structurally valid input to the explicitly + # unsupported SSPA adjudication; it is not a claim about their earnings. + person = i.Person( + date(1960, 1, 2), alien_worker=True, ssn_never_assigned=True + ) + month = date(2026, 1, 1) + years = { + year: i.CoverageYear( + i.EarningsProvenance.OBSERVED, + **( + {"qc_count": 0} + if year >= 1978 + else {"qc_quarters": (False,) * 4} + ), + ) + for year in range(1960, 2027) + } + outcome = i.evaluate_insured_status( + example_id, + Fraction(1), + lambda: i.insured_status(person, years, month), + ) + assert ( + outcome.unsupported.reason is i.InsuredUnsupportedReason.ALIEN_WORKER + ) + denominator = count_family_outcomes((outcome,)) + assert denominator.rows == denominator.unsupported_rows == 1 + + +def test_never_assigned_ssn_cannot_also_have_an_assignment_date(): + from populace_dynamics.track_b import insured_status as i + from populace_dynamics.track_b.gross_benefits import InvalidFamilyInput + + with pytest.raises(InvalidFamilyInput): + i.Person( + date(1960, 1, 2), + alien_worker=True, + ssn_never_assigned=True, + ssn_assignment_date=date(2004, 1, 2), + ) + + +def poms_qc_chart(): + text = source_text("poms_rs_00301_250") + result = {} + pattern = r"(\d{4})(?: – (\d{4}))? \$([\d,]+) \$([\d,]+)" + for start, end, amount, maximum in re.findall(pattern, text): + amount, maximum = int(amount.replace(",", "")), int( + maximum.replace(",", "") + ) + assert maximum == amount * 4 + for year in range(int(start), int(end or start) + 1): + result[year] = amount + assert set(result) == set(range(1978, 2027)) + return result + + +def oact_qc_chart(): + text = source_text("ssa_oact_qc").split( + "Amount of earnings needed to earn one quarter of coverage" + )[-1] + result = { + int(year): int(amount.replace(",", "")) + for year, amount in re.findall(r"\b(\d{4}) \$?([\d,]+)", text) + } + assert set(result) == set(range(1978, 2028)) + return result + + +def test_poms_and_oact_qc_charts_agree_every_shared_year(): + poms, oact = poms_qc_chart(), oact_qc_chart() + assert poms == {year: oact[year] for year in poms} + assert poms[2010] == poms[2011] == 1120 + + +def test_module_qc_amounts_match_both_published_charts(): + from populace_dynamics.track_b._insured_status_qc import QC_AMOUNTS + + assert dict(QC_AMOUNTS) == oact_qc_chart() + + +@pytest.mark.parametrize("year", range(1979, 2027)) +def test_213d_formula_against_published_chart_and_nawi_bundle(year): + from populace_dynamics.track_b._insured_status_qc import ( + _qc_amount_from_nawi, + ) + + nawi = json.loads((DATA / "ret_history.json").read_text())["nawi"] + # Exact decimal strings, with no float conversion or tolerance. + chart = poms_qc_chart() + actual = _qc_amount_from_nawi( + Fraction(nawi[str(year - 2)]), chart[year - 1] + ) + assert actual == chart[year] + + +def test_nawi_bundle_is_verified_against_its_original_capture(): + source_dir = DATA / "ret_sources" + manifest = json.loads((source_dir / "manifest.json").read_text()) + entry = next( + s for s in manifest["sources"] if s["id"] == "ssa_nawi_history" + ) + data = (source_dir / entry["file"]).read_bytes() + assert hashlib.sha256(data).hexdigest() == entry["sha256"] + text = html.unescape(re.sub(r"<[^>]+>", " ", data.decode())) + text = " ".join(text.split()) + for year, value in json.loads((DATA / "ret_history.json").read_text())[ + "nawi" + ].items(): + assert f"{year} {Decimal(value):,.2f}" in text + + +def cfr_cohort_chart(): + """Return (birth-band text, male requirement, female requirement).""" + root = ET.parse(SOURCES / "ecfr_20cfr404_subpart_b.xml").getroot() + section = next( + node for node in root.iter("DIV8") if node.get("N") == "404.115" + ) + result = [] + for row in section.findall(".//TBODY/TR"): + cells = [ + " ".join("".join(cell.itertext()).split()) + for cell in row.findall("TD") + ] + # The open-ended final row prints 40 once for both sex columns. + result.append((cells[0], int(cells[1]), int(cells[2] or cells[1]))) + assert len(result) == 38 + return tuple(result) + + +def test_cfr_cohort_chart_is_complete_and_has_male_transition_rows(): + chart = cfr_cohort_chart() + assert chart[0] == ("Jan. 1, 1893 or earlier", 6, 6) + assert chart[-1] == ("Jan. 2, 1929 or later", 40, 40) + assert [row[1] for row in chart if "Jan. 2, 191" in row[0]][:4] == [24] * 4 + + +def test_rs00301_800_chart_attachment_is_explicitly_unavailable(): + raw = (SOURCES / "poms_rs_00301_800.html").read_text() + assert "G-RS_00301.800-1.gif" in raw + assert "G-RS_00301.800-2.gif" in raw + assert "G-RS_00301.800-1.pdf" in raw + assert not tuple(SOURCES.glob("*.gif")) + case = next( + e for e in registry()["examples"] if e["id"] == "poms_800_exhibit" + ) + assert case["coverage"] == "missing_attachment" From 3c136538da81d493467a6424427b7d678341b26f Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Fri, 23 Oct 2026 10:17:41 -0400 Subject: [PATCH 02/46] Document the Track B insured-status interface, scope and source findings The design note gives B6a and OP8(d) a citable interface: inputs, the earnings-provenance enum, the decided-despite-unknowns flag, refusal reasons and signatures. The rulespec issue draft covers 42 U.S.C. 413, 414 and 423(c)(1), which Axiom does not encode yet. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 328 ++++++++++++++++++ .../track_b_insured_status_rulespec_issue.md | 164 +++++++++ 2 files changed, 492 insertions(+) create mode 100644 docs/design/track_b_insured_status.md create mode 100644 docs/design/track_b_insured_status_rulespec_issue.md diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md new file mode 100644 index 000000000..ee72f6de5 --- /dev/null +++ b/docs/design/track_b_insured_status.md @@ -0,0 +1,328 @@ +# Track B insured status and quarters of coverage + +Verification class: **statutory conformance**. Version: `track-b-insured-v1`. +Admitted scope: invented declarations and published statutory examples only. +There is no population, behavioral, claiming-hazard, or forecast claim. +The governing reference is Act sections 213, 214, 216(i), 223(c)(1), +20 CFR part 404 subpart B, and POMS RS 00301. Sources are captured under +`tests/data/track_b/insured_status_sources/`; the example registry explicitly +separates reproduced computations from refused and unavailable examples. + +## Interface for B6a, OP8(d), and OP12 + +The public module is `populace_dynamics.track_b.insured_status`. +B6a calls `insured_status(..., test=InsuredTest.FULLY)` for a person-month +risk set. OP8(d) uses the same call with explicitly declared pre-entry years; +OP12 supplies `coverage_end_month`. There is no projection-entry input and +no chosen pre-entry convention. Missing years are input errors, not zeros. + +```python +insured_status( + person: Person, + years: Mapping[int, CoverageYear], + month: date, + *, + test: InsuredTest = InsuredTest.ALL, + coverage_end_month: date | None = None, + totalization_credits: tuple[str, ...] = (), +) -> InsuredStatus + +fully_insured_requirement(person: Person, month: date) -> int +qc_amount_from_nawi(nawi: Fraction, prior_amount: int) -> int +evaluate_insured_status( + key: str, weight: Fraction, compute: Callable[[], InsuredStatus] +) -> InsuredOutcome +``` + +Months are exact `datetime.date` values with day 1. Dates of birth, death, +onset, and disability-period boundaries retain their actual days. Age is +attained on the day before the birthday (404.102). Integer quarter IDs in +windows and assignments are `4 * year + quarter - 1`, with quarter 1–4. +Status at a hypothetical entitlement/onset month takes effect on the first +day of its calendar quarter; it can cease at the next quarter boundary or +at January's change in the fully insured requirement. This is an insured +status calculation, not entitlement, medical disability, or a payment. +Currently insured uses the supplied death date, RIB entitlement month, +or most recent DIB entitlement month when available; any qualifying event +suffices. With none supplied it tests a hypothetical event in the query +quarter (214(b); RS 00301.110). Actual event dates are retained in later +queries; an emigrant with no entitlement event continues on the query clock. +Only disability periods ending before a historical event are prior periods +for its13-quarter window; the event’s own later-ending period is not excluded. + +`Person` declares `birth_date`, optional `sex` (`Sex.MALE` or `Sex.FEMALE`, +required for pre-January-2-1913 cohorts), optional `death_date`, optional +`disability_onset`, ordered `prior_disability_periods`, +`statutory_blindness`, membership `conditions`, `alien_worker`, and optional +`ssn_assignment_date`, Boolean `ssn_never_assigned` (default `False`), and optional +`rib_entitlement_month` and `dib_entitlement_month` (the most recent DIB +entitlement). Supplied entitlement months must be within the lifetime and +no later than the query. An SSN assignment cannot precede birth. An alien +worker must declare either an assignment date or `ssn_never_assigned=True`; +supplying both is an input error. Never-assigned alien workers and those +whose first assignment was on or after January 1, 2004 receive the named +SSPA 211 refusal (RS 00301.102); missing SSN facts do not silently imply +that the additional requirement is satisfied. +A `DisabilityPeriod` declares +`start`, `end`, and `special_insured`: the latter is an adjudicated fact +that the earlier period qualified only under the special young-worker test. +Periods must not overlap calendar quarters. Onset may be later within the +query month, but not in a later month. A nonblind declared onset anchors the +disability witness; this preserves the onset test without claiming to +adjudicate the waiting period or a continuous disability freeze (.120). + +Every year from `max(1937, birth_date.year)` through the earliest of query, +death, or coverage-end year must appear exactly once. Mapping iteration +order does not change a result. Years may declare either earnings or QCs, +never both. `CoverageYear` has a required canonical `EarningsProvenance`: + +| Provenance | Values and treatment | +| --- | --- | +| `OBSERVED` | An explicit earnings or QC declaration; the rule does not verify how it was observed. | +| `CONVENTION_FILLED` | The same declaration plus a nonempty `convention_id`; amounts have identical statutory treatment. | +| `UNKNOWN` | No earnings or QC values allowed. Evaluate all-zero and maximum feasible-QC bounds. | + +Before 1978, direct QCs require `qc_quarters`, exactly four Boolean flags; +otherwise use four `quarterly_wages`, optional `self_employment`, and +optional separate `agricultural_wages` for 1955–77. A bare pre-1978 count is +invalid. After 1977, direct input is `qc_count` (integer 0–4); earnings are +`wages` and/or `self_employment`, including covered agricultural wages in +`wages`. Unspecified components within a declared earnings record are zero; +an unspecified earnings year is never zero. Numbers use the shared exact +number schema, normalized to `Fraction`; floating earnings are invalid. +A declaration of zero earnings or zero QCs must still declare provenance. + +All annual amounts are calendar-year covered amounts supplied by the caller. +For an exit year they must already be limited to covered work through the +exit month; the annual interface cannot reconstruct intra-year payment dates. +Subsequent years, and explicitly dated quarterly amounts or QCs after exit, +are input errors. Annual counts are capped by the number of assignable +quarters. No quarters after death, before birth, after exit, or not yet +begun at the query can be assigned. Disability interiors are excluded when +the prior periods are used (404.146; RS 00301.240). + +For example, a person born February 2, 1980 with four QCs in each year +2011–2020 and an exit in December 2020 is fully, currently, and disability +insured at exit. Querying January 2031 preserves the same 40 QCs but returns +fully insured, not currently insured, and not disability insured. The +elapsed-year requirement continues to grow and the 13- and 40-quarter clocks +keep running. Foreign coverage is represented by optional ordered nonempty +string identifiers in `totalization_credits`; empty changes nothing and any +nonempty declaration receives `totalization_credits_unsupported`. + +`InsuredStatus` reports `fully`, `currently`, and `disability` decisions +(unrequested decisions are `None`), `qcs_by_year` count ranges, a canonical +lower-bound `assigned_quarters` mapping, `unknown_years`, +`convention_years`, `decided_despite_unknowns`, `dli`, `month`, and `version`. +Each `StatusDecision` supplies `insured`, `qc_count_lower`, `qc_count_upper`, +`required`, `window`, `assigned_quarters`, and `rule`, with corresponding +`upper_required`, `upper_window`, `upper_assigned_quarters`, and `upper_rule`. +It also reports the fully insured prerequisite separately through +`fully_required`, `upper_fully_required`, `fully_qc_count_lower`, and +`fully_qc_count_upper`. Thus a disability witness can show 20 recent QCs +and still be uninsured because its duration-of-work requirement is not met. +The low and high witnesses each optimize assignment for that particular +test. They need not have the same assignment or prior-period treatment. +The per-year QC mapping uses the disability-excluded context; the witness +identifies credits actually used if disregarding the periods is favorable. + +If either bound differs on a requested Boolean status, the call raises the +sealed `unknown_earnings_years_decide_status` refusal. If both agree, the +answer is decided despite unknown years and records all such years. A caller +interested only in fully insured status selects `FULLY`, so uncertainty in +another test cannot hide an otherwise decidable answer. No convention is +inferred. Every convention-filled year and its identifier is disclosed even +if it is outside the decisive recent-work window. + +`DLIRange.lower` and `.upper` are last-quarter-end dates; `None` is the +bottom bound meaning no insured quarter. Without an exit declaration, this +is DLI **through the query**, with `right_censored=True` if still insured; +future undeclared work is not assumed zero. An uncensored historical result +still describes only the declared record through the query; later work can +reestablish insured status and move its eventual DLI. A future exit does +not remove censoring before that exit is reached. With an exit already reached, +coverage is frozen and the search can continue to the quarter before FRA +attainment, or death if earlier (RS 00301.148). DLI itself can remain a +range when the requested current statuses agree. Unknown future earnings +must not be inferred from this range or from a censored result. + +## Exact rules and supported configurations + +| Part | Implemented rule and authority | +| --- | --- | +| Annual QCs, 1978–2027 | Floor total covered wages plus SE income by the captured QC increment, maximum four (213(a); 404.143; RS .220/.250). Direct counts also work after 2027. | +| QC index | $250 × NAWI(y−2)/$9,226.48, nearest $10, ties upward, no decrease from the previous amount (213(d); OACT). No float tolerance. | +| Pre-1978 wages | $50 in a quarter; maximum taxable wages or qualifying combined wages/SE give four gift QCs (213(a); 404.141; RS .310/.345). | +| Calendar-year SE | At least $400 gives four QCs from 1951; below $400 contributes only to the applicable maximum-earnings rule (RS .340/.345). | +| Agriculture | 1955–77 annual $100 increments, up to four, added to uncredited quarters. Covered 1951–54 agricultural wages must already be included in quarterly covered wages (RS .320/.325). | +| Flexible assignment | Assign annual credits to whichever allowed quarters favor each test. Distinct tests expose distinct witnesses (404.143/.145; RS .230). | +| Fully insured | One QC per elapsed year after 1950 or age 21 year, minimum six, maximum 40; stop before query, age 62, death, or applicable onset year; exclude years partially or wholly in a used disability period (214(a);404.110;RS .105). | +| Early male retirement cohorts | Before January 2, 1911 use age 65; January 2, 1911–January 1, 1913 use 1975, subject to earlier query/death (404.110; RS .105). | +| Early male disability prerequisite | For every man born before January 2, 1913, the disability-specific fully insured elapsed-year endpoint is 1975 or the earlier relevant disability year (404.132(b)). It can differ from the retirement fully insured decision. | +| Currently insured | Six QCs within 13 counted quarters ending with an actual declared death/RIB/DIB event, or the hypothetical query event (214(b);404.120;RS .110). | +| Disability | Fully insured plus 20 QCs in 40 counted quarters (223(c)(1);216(i)(3);404.130;RS .120/.130). | +| Young worker | Before the age 31 attainment quarter: half the quarters after the age 21 quarter, dropping an odd remainder, minimum six. Fewer than 12 elapsed quarters uses 6/12; age 24 attainment quarter still uses 6/12 (404.130(c);RS .140). | +| Subsequent disability | With declared earlier special insured status, the special test can apply after 31, up to 20/40. Prior periods are all used or all disregarded, whichever admits insured status; endpoints count in windows only if QCs (404.130(f);RS .120/.147). | +| Blindness | Fully insured only, with elapsed years continuing until the qualifying QC year if onset itself was not insured (RS .150). | +| DLI | Latest fully-and-disability-insured quarter end, with explicit query censoring or frozen-exit horizon and FRA cap (RS .148). | + +For prior disability periods, only years containing their endpoint quarters +need assignment enumeration. Other annual credits maximize overlap directly. +The calculation considers all-used and all-disregarded contexts, never a +selectively chosen subset. More than 4,096 boundary combinations receive an +explicit computational-coverage refusal. No approximate search is used. + +For example, a man born February 2, 1900 queried in December 1974 with +20 QCs from 1969–1973 needs 14 QCs under the retirement fully insured rule, +but 23 for the disability prerequisite. The result is fully insured and +meets the disability 20/40 test, while remaining disability uninsured. +`fully_insured_requirement` returns the retirement/general requirement; +the disability decision's prerequisite fields expose the separate 404.132 +calculation. This example decides insurance tests only, not post-FRA benefit +entitlement. + +## Refused configurations + +Input errors are raised before any of these coverage decisions. The enum is +`InsuredUnsupportedReason`; the class is `InsuredConfigurationUnsupported`, +a subclass of the shared `FamilyConfigurationUnsupported`. + +| Trigger | Reason code | +| --- | --- | +| Unknown-year bounds decide a requested status differently | `unknown_earnings_years_decide_status` | +| Any foreign totalization credits | `totalization_credits_unsupported` | +| Declared deemed nonprofit/veteran fully insured path | `deemed_fully_insured_unsupported` | +| Declared transitional insured path | `transitional_insured_unsupported` | +| Alien SSN never assigned, or first assigned on/after January 1, 2004 | `alien_worker_sspa211_unsupported` | +| Railroad or military credits | `railroad_credits_unsupported`, `military_credits_unsupported` | +| Medicare-qualified government employment | `medicare_government_employment_unsupported` | +| Earned-basis wages or pre1956 alternate disability | `earned_basis_unsupported`, `disability_before_1956_unsupported` | +| Fiscal or short taxable-year public declaration | `fiscal_taxable_year_unsupported`, `short_taxable_year_unsupported` | +| Simplified pre1951 aggregate computation | `simplified_pre1951_unsupported` | +| Positive raw1937 earnings needing half-year/age65 rules | `1937_earnings_allocation_unsupported` | +| Separate pre1955 agricultural annual wages | `pre1955_agricultural_allocation_unsupported` | +| Pre1951 self-employment income | `pre1951_self_employment_unsupported` | +| Earnings require an increment after 2027 | `qc_amount_year_unsupported` | +| Query before 1968; blind query before 1973; subsequent-special query before May 1983 | `entitlement_before_1968_unsupported`, `blindness_before_1973_unsupported`, `subsequent_special_before_1983_unsupported` | +| More than 4,096 disability-boundary combinations | `disability_boundary_assignments_unsupported` | + +A `CoverageCondition` explicitly triggers each specialist refusal. The +module does not infer excluded specialist facts from ordinary earnings. +Fiscal/short-year allocation helpers execute source arithmetic privately +for conformance tests; they do not expand the public calendar-year API. + +## Input and result contract + +The shared `_provenance` schema checks exact built-in scalar types, canonical +enums, exact declared classes, and every raw mapping element before hashing. +Ordered `tuple`/`list` inputs become tuples; membership conditions become a +frozenset. Sets are not accepted for ordered quarters, periods, or credits. +Dates are exact dates, Boolean values cannot impersonate integers, and +floating earnings are rejected. Public calls validate and snapshot once. +A new schema entry marks this module's earnings as exact, alongside R2/R3. +No cached caller identity bypasses later validation. + +All decisions, DLI ranges, aggregate results, refusals, outcomes, and shared +denominators are sealed. Public construction, copying, dataclass replacement, +serialization, and mutated result reuse fail. Persist declared inputs and +recompute. `evaluate_insured_status` accepts only genuine results from this +layer but retains genuine shared coverage refusals. `count_family_outcomes` +counts all supported and refused rows and weights. Invalid declarations +produce no outcome row. The seal is an API contract, not a security boundary +against callers reaching private Python names or monkeypatching modules. + +## Executed invariants + +The test modules named below provide example assertions and Hypothesis +properties. The final execution report lists exact commands and results. + +- Annual QCs stay in 0–4 and never decrease as earnings increase: + `test_qcs_bounded_and_monotone_in_earnings`, + `test_pre1978_qcs_bounded_and_monotone`. +- Indexed QC amounts never fall below the previous increment and are + monotone in NAWI: `test_qc_amount_prior_floor_and_nawi_monotonicity`. +- Assignments are deterministic, order independent, unique, allowed, + preserve permitted fixed quarters, and maximize overlap with their window: + `test_assignment_maximizes_window_and_is_order_independent`. +- Excluding disability interiors never adds a QC and preserves eligible + endpoints: `test_disability_exclusion_never_adds_qc` and the public + `test_property_disability_period_exclusion_never_adds_qcs`. +- Every insured status and DLI are monotone when a QC is added; disability + insured implies fully insured: + `test_property_status_and_dli_monotone_in_quarters` and + `test_property_subsequent_special_and_dli_monotonic`. +- Unknown status, count, and DLI bounds contain every concrete filling or + the rule refuses: `test_property_unknown_bounds_cover_every_filling`, + `test_unknown_bounds_with_prior_disability_period`, and + `test_unknown_birth_and_exit_year_cap_is_sound`. +- Convention labels change no statutory answer and input order changes no + result; complete observed histories follow the ordinary path: + `test_property_convention_equal_amounts_and_order_independence`. +- Current/ordinary disability windows contain exactly 13/40 counted + quarters, fully insured requirements stay in 6–40, the initial special + test applies only before the age 31 attainment quarter, and blindness + requires only fully insured: + `test_property_windows_and_blindness_rule`, with the boundary example + `test_special_insured_quarter_before_31_boundary`. +- Invalid input cannot become a refusal row; every valid refusal remains + in the shared row and weight denominator: + `test_property_input_errors_are_atomic_before_refusal` and + `test_property_refusal_denominator_conserves_rows_and_weights`. +- Exact fiscal allocation conserves supplied income: + `test_exact_sei_allocation_conserves_income`. This is private worked + arithmetic, not an expansion of the public supported configuration. + +Boundary examples additionally pin actual-event windows and future-exit +censoring: `test_currently_insured_uses_death_quarter_after_death`, +`test_currently_insured_preserves_actual_entitlement_event`, +`test_currently_insured_accepts_any_statutory_event`, and +`test_future_exit_does_not_remove_dli_censoring`. The separate early-male +disability prerequisite is pinned by +`test_pre1911_male_dib_fully_requirement_uses_1975_cap_cfr_404_132`. + +## Worked examples and source findings + +The YAML registry records source literals, expectations, coverage labels, +and any divergence. Source tests hash every capture and verify every quoted +rule and every example figure verbatim after documented text normalization. +The QC table matches POMS 1978–2026 and OACT 1978–2027 exactly. The repository +NAWI bundle reproduces every computable increment 1979–2026 with zero +arithmetic tolerance. OACT 2027 gives $250 × $72,800.33 / $9,226.48 = +$1,972.59 as printed, then rounds to $1,970, above 2026's $1,890. + +RS .140 Fred Brown has 35 elapsed quarters, drops the odd quarter to 34, +and needs 17 QCs. Sam White has seven elapsed quarters and needs six QCs +in the 12-quarter 1981Q3–1984Q2 window. Mary Smith's examples 3–5 test six +recent credits, insufficiently recent credits, and favorable reassignment +of a 1982 credit to Q4. RS .148's person born March 9, 1954 has 30 total QCs, +needs 14 for fully insured in 1990, and has DLI June 30, 1990 by assigning +1980's two annual credits to Q3/Q4. RS .150 Calvin Hill needs seven QCs in +1986; the sixth in Q1 is insufficient and the seventh makes him insured +April 1, 1986. These calculations are pinned directly in the public tests. + +RS .800's capture is an HTML shell linking uncaptured GIF/PDF exhibits. +The claimed all-cohort POMS differential cannot be performed offline. +Instead the tests compare every captured CFR 404.115 cohort row, including +January 1/January 2 boundaries and sex distinctions. RS .149 similarly links +an uncaptured worksheet. Neither missing attachment is represented as read. + +RS .340 prints $10,900 in SEI but allocates $3,600 to each of three +quarters. Literal covered SEI divides as $10,900/3. An unstated application +of the1973 taxable ceiling of $10,800 instead reproduces $3,600 exactly, +if $10,900 meant net earnings before that ceiling. Tests execute both +readings; both give three QCs. The public short-year path remains refused. RS .345 prints an impossible “after 1975 and before 1975” +SE fiscal bracket; the calendar 1975 maximum of $14,100 is independently +clear in its wage table. No fiscal interpretation is silently inferred. +The subsequent-disability examples are also checked against the operative +endpoint and all-periods-disregarded rules; the final report records any +executed divergence and the exact supporting text for review. + +## Not in scope + +No real data, population evaluation, baseline claiming hazard, behavioral +response, benefit amount, administrative entitlement adjudication, medical +finding, original SSN evidence, or totalization agreement is implemented. +This module supplies B6a's statutory insured-status predicate; it does not +establish the empirical risk denominator or admit B6a forecasting. OP8(d)'s +pre-entry convention remains Max's decision. No Axiom differential is +claimed: the companion issue draft requests pinned413/414/423(c)(1) rules. diff --git a/docs/design/track_b_insured_status_rulespec_issue.md b/docs/design/track_b_insured_status_rulespec_issue.md new file mode 100644 index 000000000..a5272af23 --- /dev/null +++ b/docs/design/track_b_insured_status_rulespec_issue.md @@ -0,0 +1,164 @@ +# Draft rulespec-us dispatch: insured status and quarters of coverage + +Verification class: statutory conformance. Required expectations come from +published statutory cases and invented declarations only; this issue admits +no population, behavioral or forecast claim. This draft is not filed. + +Suggested issue title: `Encode 42 USC 413, 414 and 423(c)(1): quarters of +coverage and fully/currently/disability insured status`. + +The offline workspace does not contain rulespec-us issues #1403 or #1416. +The structure below approximates the requested dispatch format; the +orchestrator must map its field names to those templates before filing. +No request was made to GitHub or any other external service. + +## Problem and dispatch scope + +The task brief reports that rulespec-us encodes 402, 415, 416(l) and 426, +but has no pinned 413, 414 or 423(c) rule. Consequently the Python reference +cannot yet run an Axiom differential for insured status. Add the statutory +rules below and companion examples, then supply the immutable rule revision, +corpus revision, module hashes and runtime contract. A differential remains +diagnostic until those exact versions are pinned; it does not establish +population validation. + +Proposed module paths follow the `us/statutes/42/415/a.yaml` convention +already recorded in this repository. They are proposed paths, not a claim +that files exist in a remote checkout: + +| Proposed module | Corpus authority | Required responsibility | +| --- | --- | --- | +| `us/statutes/42/413/a.yaml` | 42 USC 413(a), 20 CFR 404.140-.146 | Quarterly and annual credits, favorable assignment, exclusions | +| `us/statutes/42/413/b.yaml` | 42 USC 413(b) | 1937 half-year allocation or explicit named refusal | +| `us/statutes/42/413/c.yaml` | 42 USC 413(c) | Simplified pre-1951 rule or explicit named refusal | +| `us/statutes/42/413/d.yaml` | 42 USC 413(d), POMS RS 00301.250, OACT QC | Exact QC increment with NAWI indexing, nearest-ten rounding and prior-year floor | +| `us/statutes/42/414/a.yaml` | 42 USC 414(a), 20 CFR 404.110/.115, POMS RS 00301.105 | Fully insured requirement and result | +| `us/statutes/42/414/b.yaml` | 42 USC 414(b), 20 CFR 404.120, POMS RS 00301.110 | Six-in-thirteen current insurance | +| `us/statutes/42/414/c.yaml` | 42 USC 414(c), POMS RS 00301.102 | Alien criterion or explicit named refusal | +| `us/statutes/42/423/c/1.yaml` | 42 USC 423(c)(1), 416(i)(3), 20 CFR 404.130-.131 | Fully insured plus 20/40, young-worker/subsequent special alternatives, blindness | +| `us/policies/ssa/quarter-of-coverage/1978-2027.yaml` | POMS RS 00301.250 and SSA OACT QC | Pinned published calendar-year QC increments | + +The caller supplies birth and event dates, canonical sex where the historical +male rule requires it, blindness, disability periods, and year-keyed covered +earnings or direct QCs. Post-1977 direct QCs are annual counts; pre-1978 +direct QCs identify quarters. No year is implicitly zero. Each year has +observed, named convention-filled or unknown provenance. A coverage-end +month stops assignment while elapsed-year and recent-work clocks continue. +A nonempty foreign-totalization input is explicitly refused until encoded. + +Required outputs are annual QC ranges, favorable assigned-quarter witnesses, +fully/currently/disability insurance, required counts and decision windows, +DLI or a DLI range, unknown years, convention identifiers and the +`decided_despite_unknowns` flag. Each unsupported configuration must return a +named refusal retained in the shared evaluator denominator. Malformed input +must fail before any coverage refusal. Output and refusal records must bind +the rule revision and input declaration. + +## Pasteable review_finding + +```json +{ + "review_finding": { + "kind": "missing_statutory_rule", + "severity": "blocking_for_differential", + "citations": ["42 USC 413", "42 USC 414", "42 USC 423(c)(1)", "42 USC 416(i)(3)"], + "finding": "Insured-status decisions require statutory quarter-of-coverage assignment and fully/currently/disability insured rules that are not pinned in the supplied rulespec-us surface.", + "requested_change": "Encode the cited provisions with exact arithmetic, explicit support/refusal boundaries, date-based windows, provenance-aware unknown-year bounds and the captured worked cases. Provide immutable rule and corpus identities before enabling an Axiom differential.", + "evidence": "PolicyEngine/microcosm-dynamics tests/data/track_b/insured_status_sources/manifest.json and insured_status_examples.yaml", + "acceptance": "All supported captured cases reproduce exactly; source errata remain separate from statutory results; every refusal remains in the denominator; malformed input is not counted; every invariant has a property test and deliberate mutations fail." + } +} +``` + +## Companion tests + +Expectations must come from the same captures, independently of the Python +implementation. Use `tests/data/track_b/insured_status_examples.yaml` as the +case inventory, preserving its coverage labels. In particular: + +- RS 00301.250 and OACT: every shared 1978-2026 QC amount agrees, 2010 and + 2011 each require $1,120; OACT 2027 uses $250 × $72,800.33 / $9,226.48, + shown as $1,972.59 and rounded to $1,970, above the $1,890 prior amount. +- RS 00301.140 Fred: 35 elapsed quarters, odd count reduced to 34, requiring + 17 QCs. Sam: six QCs in the twelve quarters ending 1984Q2. Mary: six in + the proper twelve-quarter period qualifies; credits outside that period + do not; movable 1982 credits may be assigned to 1982Q4. +- RS 00301.148: birth March 9, 1954, 30 total QCs, 14 needed to be fully + insured in 1990, DLI June 30, 1990 after favorable 1980 reassignment. + FRA in November 2019 limits DLI to September 30, 2019. +- RS 00301.150 Calvin: six QCs in 1986Q1 are short of the seven required; + 1986Q2 supplies the seventh and insurance begins April 1, 1986. +- RS 00301.320 Jane: $400 covered agricultural wages plus the already + qualifying $50 nonagricultural quarter yields four QCs, never five. + RS 00301.230 Henry's $1,500 and .325 John's $1,200 in 2010 each produce + one annual QC assignable to 2010Q1. +- RS 00301.220: fiscal $12,000 allocates $3,000/$9,000. CFR 404.144's + $1,200 May-to-May example allocates $700/$500. RS 00301.340's regular + fiscal example allocates $10,800 equally as four $2,700 amounts. +- RS 00301.340 short-year ambiguity: the source labels $10,900 as SEI + but prints three $3,600 allocations. Literal already-covered SEI divides + as $10,900/3. Alternatively, an unstated $10,800 contribution-base + ceiling for the taxable year beginning in 1973, identified in .345 and + Act 213(a)(2)(B)(iii), gives exactly three $3,600 allocations if $10,900 + meant net earnings before the ceiling. Execute both readings and seek + clarification; do not declare a proven arithmetic erratum or silently + infer the ceiling. Both give three QCs, but allocated earnings differ + by $100. Public short-taxable-year status remains a named refusal. +- RS 00301.345 fiscal gift examples produce four, five and five QCs across + the taxable-year span; no calendar year may exceed four. Preserve its + impossible printed “after 1975 and before 1975” interval as a source + defect rather than silently inventing its intended fiscal boundary. +- Compare fully-insured requirements against every captured CFR 404.115 + birth-cohort row, including historical male transitions and January 1 + birthdays. The RS 00301.800 HTML lacks the linked exhibit's bytes, so + request the exhibit capture before claiming a .800 differential. +- Exercise subsequent disability .140/.147 examples with all-or-none freeze + handling and creditable endpoint quarters. Preserve any source-versus-rule + discrepancy documented by the Python lane; do not make the compiler + imitate an erratum to force parity. +- Explicitly refuse unsupported deemed, alien, military/railroad, Medicare, + earned-basis, old-law and totalization inputs. A coverage refusal is not + evidence that the published person's legal conclusion was negative. + +Properties must establish QC and status monotonicity, DLI monotonicity, +0–4 calendar-year bounds, exact window lengths after exclusions, +disability-implies-fully, deterministic order independence, unknown-year +bound soundness and convention transparency. Require at least eight +one-line mutations, report failing test names and revert every mutation. + +## Verbatim captured law + +The following paragraphs are copied from the pinned LII text excerpts after +the same documented whitespace and apostrophe normalization as the source +tests. No live source has been consulted. The complete original response +identities remain in each manifest entry's `served_bodies`. + +### 42 USC 413 + +Corpus URL: https://www.law.cornell.edu/uscode/text/42/413. Captured 2026-10-21T13:57:14Z; excerpt SHA-256 `b45a823d4376fbb41f40acf31b5df62284afcdf7373c84491bb08df54abfad44`. + +> (a) Definitions For the purposes of this subchapter— (1) The term “quarter”, and the term “ calendar quarter ”, mean a period of three calendar months ending on March 31, June 30, September 30, or December 31. (2) (A) The term “ quarter of coverage ” means— (i) for calendar years before 1978, and subject to the provisions of subparagraph (B), a quarter in which an individual has been paid $50 or more in wages (except wages for agricultural labor paid after 1954) or for which he has been credited (as determined under section 412 of this title ) with $100 or more of self-employment income; and (ii) for calendar years after 1977, and subject to the provisions of subparagraph (B), each portion of the total of the wages paid and the self-employment income credited (pursuant to section 412 of this title ) to an individual in a calendar year which equals the amount required for a quarter of coverage in that calendar year (as determined under subsection (d)), with such quarter of coverage being assigned to a specific calendar quarter in such calendar year only if necessary in the case of any individual who has attained age 62 or died or is under a disability and the requirements for insured status in subsection (a) or (b) of section 414 of this title , the requirements for entitlement to a computation or recomputation of his primary insurance amount, or the requirements of paragraph (3) of section 416(i) of this title would not otherwise be met. (B) Notwithstanding the provisions of subparagraph (A)— (i) no quarter after the quarter in which an individual dies shall be a quarter of coverage , and no quarter any part of which is included in a period of disability (other than the initial quarter and the last quarter of such period) shall be a quarter of coverage ; (ii) if the wages paid to an individual in any calendar year equal $3,000 in the case of a calendar year before 1951, or $3,600 in the case of a calendar year after 1950 and before 1955, or $4,200 in the case of a calendar year after 1954 and before 1959, or $4,800 in the case of a calendar year after 1958 and before 1966, or $6,600 in the case of a calendar year after 1965 and before 1968, or $7,800 in the case of a calendar year after 1967 and before 1972, or $9,000 in the case of the calendar year 1972, or $10,800 in the case of the calendar year 1973, or $13,200 in the case of the calendar year 1974, or an amount equal to the contribution and benefit base (as determined under section 430 of this title ) in the case of any calendar year after 1974 and before 1978 with respect to which such contribution and benefit base is effective, each quarter of such year shall (subject to clauses (i) and (v)) be a quarter of coverage; (iii) if an individual has self-employment income for a taxable year, and if the sum of such income and the wages paid to him during such year equals $3,600 in the case of a taxable year beginning after 1950 and ending before 1955, or $4,200 in the case of a taxable year ending after 1954 and before 1959, or $4,800 in the case of a taxable year ending after 1958 and before 1966, or $6,600 in the case of a taxable year ending after 1965 and before 1968, or $7,800 in the case of a taxable year ending after 1967 and before 1972, or $9,000 in the case of a taxable year beginning after 1971 and before 1973, or $10,800 in the case of a taxable year beginning after 1972 and before 1974, or $13,200 in the case of a taxable year beginning after 1973 and before 1975, or an amount equal to the contribution and benefit base (as determined under section 430 of this title ) which is effective for the calendar year in the case of any taxable year beginning in any calendar year after 1974 and before 1978, each quarter any part of which falls in such year shall (subject to clauses (i) and (v)) be a quarter of coverage; (iv) if an individual is paid wages for agricultural labor in a calendar year after 1954 and before 1978, then, subject to clauses (i) and (v), (I) the last quarter of such year which can be but is not otherwise a quarter of coverage shall be a quarter of coverage if such wages equal or exceed $100 but are less than $200; (II) the last two quarters of such year which can be but are not otherwise quarters of coverage shall be quarters of coverage if such wages equal or exceed $200 but are less than $300; (III) the last three quarters of such year which can be but are not otherwise quarters of coverage shall be quarters of coverage if such wages equal or exceed $300 but are less than $400; and (IV) each quarter of such year which is not otherwise a quarter of coverage shall be a quarter of coverage if such wages are $400 or more; (v) no quarter shall be counted as a quarter of coverage prior to the beginning of such quarter; (vi) not more than one quarter of coverage may be credited to a calendar quarter; and (vii) no more than four quarters of coverage may be credited to any calendar year after 1977. If in the case of an individual who has attained age 62 or died or is under a disability and who has been paid wages for agricultural labor in a calendar year after 1954 and before 1978, the requirements for insured status in subsection (a) or (b) of section 414 of this title , the requirements for entitlement to a computation or recomputation of his primary insurance amount, or the requirements of paragraph (3) of section 416(i) of this title are not met after assignment of quarters of coverage to quarters in such year as provided in clause (iv) of the preceding sentence, but would be met if such quarters of coverage were assigned to different quarters in such year, then such quarters of coverage shall instead be assigned, for purposes only of determining compliance with such requirements, to such different quarters. If, in the case of an individual who did not die prior to January 1, 1955 , and who attained age 62 (if a woman) or age 65 (if a man) or died before July 1, 1957 , the requirements for insured status in section 414(a)(3) of this title are not met because of his having too few quarters of coverage but would be met if his quarters of coverage in the first calendar year in which he had any covered employment had been determined on the basis of the period during which wages were earned rather than on the basis of the period during which wages were paid (any such wages paid that are reallocated on an earned basis shall not be used in determining quarters of coverage for subsequent calendar years), then upon application filed by the individual or his survivors and satisfactory proof of his record of wages earned being furnished by such individual or his survivors, the quarters of coverage in such calendar year may be determined on the basis of the periods during which wages were earned. + +> (b) Crediting of wages paid in 1937 With respect to wages paid to an individual in the six-month periods commencing either January 1, 1937 , or July 1, 1937 ; (A) if wages of not less than $100 were paid in any such period, one-half of the total amount thereof shall be deemed to have been paid in each of the calendar quarters in such period; and (B) if wages of less than $100 were paid in any such period, the total amount thereof shall be deemed to have been paid in the latter quarter of such period, except that if in any such period, the individual attained age sixty-five, all of the wages paid in such period shall be deemed to have been paid before such age was attained. + +> (c) Alternative method for determining quarters of coverage with respect to wages in period from 1937 to 1950 For purposes of sections 414(a) and 415(d) of this title, an individual shall be deemed to have one quarter of coverage for each $400 of his total wages prior to 1951 (as defined in section 415(d)(1)(C) of this title ), except where such individual is not a fully insured individual on the basis of the number of quarters of coverage so derived plus the number of quarters of coverage derived from the wages and self-employment income credited to such individual for periods after 1950. + +> (d) Amount required for a quarter of coverage (1) The amount of wages and self-employment income which an individual must have in order to be credited with a quarter of coverage in any year under subsection (a)(2)(A)(ii) shall be $250 in the calendar year 1978 and the amount determined under paragraph (2) of this subsection for years after 1978. (2) The Commissioner of Social Security shall, on or before November 1 of 1978 and of every year thereafter, determine and publish in the Federal Register the amount of wages and self-employment income which an individual must have in order to be credited with a quarter of coverage in the succeeding calendar year. The amount required for a quarter of coverage shall be the larger of— (A) the amount in effect in the calendar year in which the determination under this subsection is made, or (B) the product of the amount prescribed in paragraph (1) which is required for a quarter of coverage in 1978 and the ratio of the national average wage index (as defined in section 409(k)(1) of this title ) for the calendar year before the year in which the determination under this paragraph is made to the national average wage index (as so defined) for 1976, with such product, if not a multiple of $10, being rounded to the next higher multiple of $10 where such amount is a multiple of $5 but not of $10 and to the nearest multiple of $10 in any other case. + +### 42 USC 414 + +Corpus URL: https://www.law.cornell.edu/uscode/text/42/414. Captured 2026-10-21T13:57:15Z; excerpt SHA-256 `deca2cfea26a61b37b847f4cd23d4820c362b6e5644622d50b9b6ee784b6fc24`. + +> (a) “Fully insured individual” defined The term “ fully insured individual ” means any individual who had not less than— (1) one quarter of coverage (whenever acquired) for each calendar year elapsing after 1950 (or, if later, the year in which he attained age 21) and before the year in which he died or (if earlier) the year in which he attained age 62, except that in no case shall an individual be a fully insured individual unless he has at least 6 quarters of coverage; or (2) 40 quarters of coverage; or (3) in the case of an individual who died before 1951, 6 quarters of coverage; not counting as an elapsed year for purposes of paragraph (1) any year any part of which was included in a period of disability (as defined in section 416(i) of this title ), and who satisfies the criterion specified in subsection (c). + +> (b) “Currently insured individual” defined The term “ currently insured individual ” means any individual who had not less than six quarters of coverage during the thirteen-quarter period ending with (1) the quarter in which he died, (2) the quarter in which he became entitled to old-age insurance benefits, (3) the quarter in which he became entitled to primary insurance benefits under this subchapter as in effect prior to August 28, 1950 , or (4) in the case of any individual entitled to disability insurance benefits, the quarter in which he most recently became entitled to disability insurance benefits, not counting as part of such thirteen-quarter period any quarter any part of which was included in a period of disability unless such quarter was a quarter of coverage, and who satisfies the criterion specified in subsection (c). + +> (c) Criterion described For purposes of subsections (a) and (b), the criterion specified in this subsection is that the individual, if not a United States citizen or national— (1) has been assigned a social security account number that was, at the time of assignment, or at any later time, consistent with the requirements of subclause (I) or (III) of section 405(c)(2)(B)(i) of this title ; or (2) at the time any such quarters of coverage are earned— (A) is described in subparagraph (B) or (D) of section 1101(a)(15) of title 8 , (B) is lawfully admitted temporarily to the United States for business (in the case of an individual described in such subparagraph (B)) or the performance as a crewman (in the case of an individual described in such subparagraph (D)), and (C) the business engaged in or service as a crewman performed is within the scope of the terms of such individual's admission to the United States . + +### 42 USC 423 (c)(1) + +Corpus URL: https://www.law.cornell.edu/uscode/text/42/423. Captured 2026-10-21T13:57:17Z; excerpt SHA-256 `c0db1ea77f2d66910fa5eb7d2fdb9bd37e2f8b31ffc0a3d8a5298a384e277a61`. + +> (c) (1) An individual shall be insured for disability insurance benefits in any month if— (A) he would have been a fully insured individual (as defined in section 414 of this title ) had he attained age 62 and filed application for benefits under section 402(a) of this title on the first day of such month, and (B) (i) he had not less than 20 quarters of coverage during the 40-quarter period which ends with the quarter in which such month occurred, or (ii) if such month ends before the quarter in which he attains (or would attain) age 31, not less than one-half (and not less than 6) of the quarters during the period ending with the quarter in which such month occurred and beginning after he attained the age of 21 were quarters of coverage, or (if the number of quarters in such period is less than 12) not less than 6 of the quarters in the 12-quarter period ending with such quarter were quarters of coverage, or (iii) in the case of an individual (not otherwise insured under clause (i)) who, by reason of section 416(i)(3)(B)(ii) of this title , had a prior period of disability that began during a period before the quarter in which he or she attained age 31, not less than one-half of the quarters beginning after such individual attained age 21 and ending with the quarter in which such month occurs are quarters of coverage, or (if the number of quarters in such period is less than 12) not less than 6 of the quarters in the 12-quarter period ending with such quarter are quarters of coverage; except that the provisions of subparagraph (B) of this paragraph shall not apply in the case of an individual who is blind (within the meaning of “blindness” as defined in section 416(i)(1) of this title ). For purposes of subparagraph (B) of this paragraph, when the number of quarters in any period is an odd number, such number shall be reduced by one, and a quarter shall not be counted as part of any period if any part of such quarter was included in a period of disability unless such quarter was a quarter of coverage. + +The companion 416(i)(1)-(3) and (l) capture is `lii_usc_42_416_excerpts.txt`, pinned in the same manifest. It supplies the disability-period definition, statutory-blindness exception and retirement-age cross-reference. From b85c1e35d7ca404593449c3f8e572044a4db54f5 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Fri, 23 Oct 2026 10:17:41 -0400 Subject: [PATCH 03/46] Recount test tiers after the insured-status tests Co-Authored-By: Claude Opus 5.5 --- tests/README-tiers.md | 4 ++-- tests/tier_counts.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/README-tiers.md b/tests/README-tiers.md index e2715c124..9af8d40c9 100644 --- a/tests/README-tiers.md +++ b/tests/README-tiers.md @@ -39,9 +39,9 @@ pytest --collect-only -q -m oracle_policyengine | tail -1 | Tier | Tests at HEAD | |---|---:| -| `unit` | 18,088 | +| `unit` | 19,321 | | `artifact` | 4,253 | | `integration_psid` | 1,450 | | `reproduction_legacy` | 520 | | `oracle_policyengine` | 308 | -| **Total** | **24,619** | +| **Total** | **25,852** | diff --git a/tests/tier_counts.json b/tests/tier_counts.json index 0303dc6ab..6159e8abf 100644 --- a/tests/tier_counts.json +++ b/tests/tier_counts.json @@ -1,7 +1,7 @@ { "schema_version": 1, "counts": { - "unit": 18088, + "unit": 19321, "artifact": 4253, "integration_psid": 1450, "reproduction_legacy": 520, From 35a2bd775ae91604655175b8ad3a8a552eb91dde Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Fri, 23 Oct 2026 10:24:53 -0400 Subject: [PATCH 04/46] Check every row of the RS 00301.800 exhibit; mark the two source-conflict lines The exhibit linked from RS 00301.800 (a PDF and two GIF renderings of the quarters-of-coverage table) was not captured, so its differential was recorded as unavailable. Its text is now captured as pdf_text (pdftotext, -layout), with the PDF and both GIFs pinned by hash. A test checks all 38 rows against fully_insured_requirement: by birth cohort (men before January 2, 1913 at age 65, women at 62), by footnote 1's January 1 rule, and by year of death. Moving the 1975 cap or the 1913 cutoff fails it. The PDF's footnote misprints the male cohort as "born before 1/2/31"; the GIF, the table itself and 20 CFR 404.132(b) say 1913. A test pins that. The decision lines for the two readings taken from 20 CFR 404.130(f) over inconsistent POMS examples are marked with their source-conflict ids: us:oasdi-insured-prior-disability-favorable-disregard and us:oasdi-insured-disability-period-endpoint-quarters. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 15 ++- .../track_b/_insured_status_qc.py | 1 + .../track_b/insured_status.py | 1 + .../data/track_b/insured_status_examples.yaml | 24 +++-- .../track_b/insured_status_sources/README.md | 23 ++-- .../insured_status_sources/manifest.json | 34 +++++- .../poms_rs_00301_800_exhibit_pdftotext.txt | 102 ++++++++++++++++++ tests/test_track_b_insured_status.py | 69 ++++++++++++ tests/test_track_b_insured_status_sources.py | 53 +++++++-- 9 files changed, 291 insertions(+), 31 deletions(-) create mode 100644 tests/data/track_b/insured_status_sources/poms_rs_00301_800_exhibit_pdftotext.txt diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index ee72f6de5..a6a79dfbe 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -300,11 +300,16 @@ needs 14 for fully insured in 1990, and has DLI June 30, 1990 by assigning 1986; the sixth in Q1 is insufficient and the seventh makes him insured April 1, 1986. These calculations are pinned directly in the public tests. -RS .800's capture is an HTML shell linking uncaptured GIF/PDF exhibits. -The claimed all-cohort POMS differential cannot be performed offline. -Instead the tests compare every captured CFR 404.115 cohort row, including -January 1/January 2 boundaries and sex distinctions. RS .149 similarly links -an uncaptured worksheet. Neither missing attachment is represented as read. +RS .800's exhibit is a PDF and two GIF renderings of the same table. Its +text was extracted from the PDF with pdftotext; the PDF and both GIFs are +pinned by hash. The tests compare every one of its 38 rows: by birth cohort +(men before January 2, 1913 at age 65, women at 62), by footnote 1's +January 1 rule, and by year of death for a worker who attained 21 before +1951. They also compare every CFR 404.115 cohort row, including January +1/January 2 boundaries and sex distinctions. The PDF's footnote misprints +the male age-65 cohort as "born before 1/2/31"; its GIF rendering, its own +table and 20 CFR 404.132(b) say January 2, 1913, which the rule follows. +RS .149 links an uncaptured worksheet, which is not represented as read. RS .340 prints $10,900 in SEI but allocates $3,600 to each of three quarters. Literal covered SEI divides as $10,900/3. An unstated application diff --git a/src/populace_dynamics/track_b/_insured_status_qc.py b/src/populace_dynamics/track_b/_insured_status_qc.py index 0496d0cbb..185bdcc42 100644 --- a/src/populace_dynamics/track_b/_insured_status_qc.py +++ b/src/populace_dynamics/track_b/_insured_status_qc.py @@ -198,6 +198,7 @@ def _allowed_quarters( for value in (through_quarter, death_quarter, coverage_end_quarter) if value is not None ) + # Source conflict us:oasdi-insured-disability-period-endpoint-quarters return tuple( quarter for quarter in _year_quarters(year) diff --git a/src/populace_dynamics/track_b/insured_status.py b/src/populace_dynamics/track_b/insured_status.py index 51614ed71..88226265b 100644 --- a/src/populace_dynamics/track_b/insured_status.py +++ b/src/populace_dynamics/track_b/insured_status.py @@ -621,6 +621,7 @@ def _assignment(rows, window, boundary): def _witness(person, credits, at, exit_month, kind, *, onset=True): end = _qid(at) best = None + # Source conflict us:oasdi-insured-prior-disability-favorable-disregard # CFR404.130(f): consider all prior periods or disregard all, favorably. for use_periods in ( (True, False) if person.prior_disability_periods else (True,) diff --git a/tests/data/track_b/insured_status_examples.yaml b/tests/data/track_b/insured_status_examples.yaml index 7b67cb5ab..4d6461991 100644 --- a/tests/data/track_b/insured_status_examples.yaml +++ b/tests/data/track_b/insured_status_examples.yaml @@ -702,15 +702,21 @@ examples: coverage: table_differential test_node: tests/test_track_b_insured_status.py::test_fully_requirement_differential_cfr_404_115_every_captured_row - id: poms_800_exhibit - source: poms_rs_00301_800 - quotes: - - Quarters of Coverage Requirements - Exhibit - - View In PDF - expected: {} - coverage: missing_attachment - note: Staged HTML links to two GIFs and a PDF; their bytes are not staged. CFR - 404.115 supplies an independent text cohort chart; do not claim the unavailable - RS 00301.800 exhibit is reproduced. + source: poms_rs_00301_800_exhibit + quotes: + - 1889 or prior 1892 1954 or prior 6 + - 1910-1913 1913 1975 24 + - 1929 or later 1991 or later 40 + expected: + first_row: 1889 or prior + last_row: 1929 or later + rows: 38 + coverage: table_differential + test_node: tests/test_track_b_insured_status.py::test_fully_requirement_differential_poms_rs_00301_800_exhibit + note: Text extracted from the exhibit PDF (pdftotext), with the PDF and both + GIF renderings pinned in served_bodies. Every row is checked by birth cohort, + by the January 1 footnote and by year of death. The PDF's footnote misprints + the male age-65 cohort as 1/2/31; the GIF and 20 CFR 404.132(b) say 1913. - id: poms_102_1_lucinda source: poms_rs_00301_102 quotes: diff --git a/tests/data/track_b/insured_status_sources/README.md b/tests/data/track_b/insured_status_sources/README.md index 81ff16163..d7e588bad 100644 --- a/tests/data/track_b/insured_status_sources/README.md +++ b/tests/data/track_b/insured_status_sources/README.md @@ -4,7 +4,7 @@ Verification class: statutory conformance. These public statutory sources support invented cases and published examples only. They admit no population, behavioral or forecast claim. -`manifest.json` pins all 44 staged captures with their URL, UTC retrieval +`manifest.json` pins all 45 captures with their URL, UTC retrieval time, byte count, SHA-256 and capture format. POMS entries additionally retain the exact transmittal and page date. The staging log was removed only after all original byte counts and hashes were verified. The source @@ -14,7 +14,7 @@ or documentary-purpose quote from every capture. The example registry at its source and distinguishes computations, refusals, errata and unavailable attachments. -The three capture formats follow the gross-benefit manifest: +The capture formats follow the gross-benefit manifest, with one addition: - `http_body`: complete decoded HTTP response, unchanged. This includes all 37 POMS sections, their table of contents and eCFR subpart B as of @@ -27,6 +27,10 @@ The three capture formats follow the gross-benefit manifest: response's byte count and hash under `served_bodies`. Excerpts retain 42 USC 413(a)-(d), 414(a)-(c), 416(i)(1)-(3) and (l), and 423(c)(1). No replacement response was fetched. +- `pdf_text`: the RS 00301.800 exhibit's text, extracted from its PDF with + pdftotext 26.09.0 (`-layout -enc UTF-8`) and kept unchanged. + `served_bodies` pins the PDF and both GIF renderings of the same table + (fetched 2026-10-23 from the POMS image store). | Source | Use | | --- | --- | @@ -40,7 +44,7 @@ The three capture formats follow the gross-benefit manifest: | RS 00301.200-.250 | Annual QCs, flexible assignment, exclusions, fiscal SE allocation and every 1978-2026 increment | | RS 00301.301-.350 | Quarterly wages, agriculture, calendar/fiscal self-employment and maximum-earnings gift QCs; railroad and simplified-method boundaries | | RS 00301.470, .475, .480, .600 | Deemed veterans, earned-basis wages, pre-1956 alternative test and vow-of-poverty refusals | -| RS 00301.800 | Exhibit shell and explicit record of missing linked images/PDF | +| RS 00301.800 and its exhibit | Exhibit shell, plus the exhibit's 38-row cohort table, checked row by row | | 20 CFR 404 subpart B | Statutory rules, worked examples and the 404.115 cohort chart | | 42 USC 413, 414, 416, 423 | Act 213, 214, 216(i)/(l), 223(c)(1) | | SSA OACT QC page | Independent 1978-2027 chart and 2027 determination | @@ -55,12 +59,13 @@ OACT agree on all 49 shared years, including POMS's joint 2010-2011 row. ## Source limitations and findings -RS 00301.800 contains links to two GIF images and one PDF, but their -response bodies were not staged. Its cohort chart cannot be reconstructed -from this capture, and no external source was fetched. CFR 404.115 does -contain a complete text cohort chart, which is used as an explicitly -identified alternative differential. RS 00301.149 likewise only points -to the SSA-1164 worksheet; no worksheet reproduction is claimed. +RS 00301.800 links to two GIF images and one PDF of its exhibit. The PDF's +text is captured as `pdf_text`, and all three bodies are pinned by hash. +Every exhibit row is compared, as is every row of CFR 404.115's cohort +chart. The PDF's footnote misprints the male age-65 cohort as "born before +1/2/31"; the GIF rendering, the exhibit's own table and 20 CFR 404.132(b) +say January 2, 1913. RS 00301.149 only points to the SSA-1164 worksheet; +no worksheet reproduction is claimed. RS 00301.340's short-year example states $10,900 of self-employment income but allocates $3,600 to each of three quarters, totaling $10,800. diff --git a/tests/data/track_b/insured_status_sources/manifest.json b/tests/data/track_b/insured_status_sources/manifest.json index 2cedc1b2e..8baf37a17 100644 --- a/tests/data/track_b/insured_status_sources/manifest.json +++ b/tests/data/track_b/insured_status_sources/manifest.json @@ -4,7 +4,8 @@ "capture_formats": { "http_body": "Complete decoded HTTP response body, unchanged from the staged capture.", "browser_text": "Rendered document text checked against the served page during staging; served_bodies pins the complete HTTP response.", - "http_text_excerpt": "Cited paragraphs of staged LII HTTP bodies after stripping tags, decoding entities, collapsing whitespace and straightening apostrophes; served_bodies pins each original complete response." + "http_text_excerpt": "Cited paragraphs of staged LII HTTP bodies after stripping tags, decoding entities, collapsing whitespace and straightening apostrophes; served_bodies pins each original complete response.", + "pdf_text": "Text of a published PDF extracted with the named extractor, unchanged; served_bodies pins the PDF and any image renderings of the same pages." }, "sources": [ { @@ -596,6 +597,37 @@ "sha256": "1e864536eb0b975f8f4d82d1ac806f57c285ab1dc2d8f9f03d34976caa02b6e7" } ] + }, + { + "file": "poms_rs_00301_800_exhibit_pdftotext.txt", + "bytes": 6401, + "sha256": "4459a0bccfc9d025973f3c9183042375780d6ee3f1a9f7e91b603490ba5a3a79", + "id": "poms_rs_00301_800_exhibit", + "citation": "POMS RS 00301.800 exhibit, Quarters of Coverage Requirements (G-RS_00301.800-1.pdf)", + "url": "https://secure.ssa.gov/apps10/public/pomsimages.nsf/gfx_num/G-RS_00301.800-1/$File/G-RS_00301.800-1.pdf", + "retrieved_at_utc": "2026-10-23T14:12:14Z", + "capture": "pdf_text", + "extractor": "pdftotext 26.09.0 (Poppler), options -layout -enc UTF-8", + "poms_transmittal": "TN 14 (04-89)", + "page_date": "08/10/2012", + "title": "RS 00301.800 - Quarters of Coverage Requirements - Exhibit - 08/10/2012", + "served_bodies": [ + { + "url": "https://secure.ssa.gov/apps10/public/pomsimages.nsf/gfx_num/G-RS_00301.800-1/$File/G-RS_00301.800-1.pdf", + "bytes": 222133, + "sha256": "9dcf53be30f06978b50e109ace88265ac38753700bb0093cb6213e01920af22f" + }, + { + "url": "https://secure.ssa.gov/apps10/public/pomsimages.nsf/gfx_num/G-RS_00301.800-1/$File/G-RS_00301.800-1.gif", + "bytes": 31188, + "sha256": "5e25a2e1dd124aa218af34b93f284049e9516612955ae1326ceff19160bd28bc" + }, + { + "url": "https://secure.ssa.gov/apps10/public/pomsimages.nsf/gfx_num/G-RS_00301.800-2/$File/G-RS_00301.800-2.gif", + "bytes": 48757, + "sha256": "65d94bae34becf54cf40e361cb6fb5668883f164efdff371122e8d2b9717efe3" + } + ] } ] } diff --git a/tests/data/track_b/insured_status_sources/poms_rs_00301_800_exhibit_pdftotext.txt b/tests/data/track_b/insured_status_sources/poms_rs_00301_800_exhibit_pdftotext.txt new file mode 100644 index 000000000..8ff8eec35 --- /dev/null +++ b/tests/data/track_b/insured_status_sources/poms_rs_00301_800_exhibit_pdftotext.txt @@ -0,0 +1,102 @@ + Quarters of Coverage Requirements + For Benefits Under Title II of the Social Security Act + (If No Prior Period of Disability Established) + + Year of Birth ˡ Year of: Fully Insured Hospital Insurance Special Age 72 Transitionally + Insured + + +Men Women Retirement ² Men Women Men Women + Death³ + Disability Onset ⁴ +1889 or prior 1892 1954 or prior 6 0 0 0 0 3 + + +1890 1893 1955 6 0 0 0 0 4 + +1891 1894 1956 6 0 0 0 0 5 + +1892 1895 1957 6 0 0 0 0 * + +1893 1896 1958 7 0 0 0 3 * + +1894 1897 1959 8 0 0 0 6 * + +1895 1898 1960 9 0 0 0 * * + +1896 1899 1961 10 0 0 3 * * + +1897 1900 1962 11 0 0 6 * * + +1898 1901 1963 12 0 0 9 * * + +1899 1902 1964 13 0 0 12 * * + +1900 1903 1965 14 0 3 * * * + +1901 1904 1966 15 0 6 * * * + +1902 1905 1967 16 0 9 * * * + +1903 1906 1968 17 3 12 * * * + +1904 1907 1969 18 6 15 * * * + +1905 1908 1970 19 9 18 * * * + +1906 1909 1971 20 12 * * * * + +1907 1910 1972 21 15 * * * * + +1908 1911 1973 22 18 * * * * + +1909 1912 1974 23 21 * * * * + +1910-1913 1913 1975 24 * * * * * + Year of Birth ˡ Year of: Fully Insured Hospital Insurance Special Age 72 Transitionally + Insured + + Men Women Retirement ² Men Women Men Women + Death ³ + Disability Onset ⁴ + 1914 1976 25 * * * * * + + 1915 1977 26 * * * * * + + 1916 1978 27 * * * * * + + 1917 1979 28 * * * * * + + 1918 1980 29 * * * * * + + 1919 1981 30 * * * * * + + 1920 1982 31 * * * * * + + 1921 1983 32 * * * * * + + 1922 1984 33 * * * * * + + 1923 1985 34 * * * * * + + 1924 1986 35 * * * * * + + 1925 1987 36 * * * * * + + 1926 1988 37 * * * * * + + 1927 1989 38 * * * * * + + 1928 1990 39 * * * * * + + 1929 or later 1991 or later 40 * * * * * + + + + +ˡ If birth on 1/1, use prior year. If birth after 1/1/30, one QC needed for each year after the year age 21 attained. +² The determining age for men born before 1/2/31 is age 65. +3 Certain survivor benefits are payable also if the worker was currently insured. +⁴20/40 also required for disability benefits; if disability prior to age 31, special provisions apply (see RS 00301.140). +⁵ Regular insured status requirements apply – see “Fully Insured” column. + \ No newline at end of file diff --git a/tests/test_track_b_insured_status.py b/tests/test_track_b_insured_status.py index 6dcc311fa..680515bcc 100644 --- a/tests/test_track_b_insured_status.py +++ b/tests/test_track_b_insured_status.py @@ -202,6 +202,75 @@ def test_fully_requirement_differential_cfr_404_115_every_captured_row(): assert tested >= 140 +def _rs00301_800_exhibit_rows(): + text = (SOURCES / "poms_rs_00301_800_exhibit_pdftotext.txt").read_text( + encoding="utf-8" + ) + rows = re.findall( + r"^\s*(\d{4}(?: or prior|-\d{4}| or later)?)\s+(\d{4})?\s*" + r"(\d{4}(?: or prior| or later)?)\s+(\d{1,2})\b", + text, + re.M, + ) + assert len(rows) == 38 + return rows + + +def test_fully_requirement_differential_poms_rs_00301_800_exhibit(): + """Every row of the RS 00301.800 exhibit, by birth cohort and death year. + + Men born before January 2, 1913 use age 65 and women age 62; from 1914 + one row serves both. Footnote 1: a January 1 birth takes the prior + year's row. The death-year column is checked for a worker who attained + 21 before 1951 (born July 1, 1929) and dies that year. + """ + tested = 0 + for men, women, event, required in _rs00301_800_exhibit_rows(): + required = int(required) + years_in_cell = [int(y) for y in re.findall(r"\d{4}", men)] + first, last = years_in_cell[0], years_in_cell[-1] + cohorts = [ + (i.Sex.MALE, date(year, 7, 1) if year < 1913 else date(1913, 1, 1)) + for year in range(first, last + 1) + if year <= 1913 + ] + if first >= 1914: + cohorts.append((i.Sex.MALE, date(first, 7, 1))) + female_year = int(women) if women else first + cohorts += [ + (i.Sex.FEMALE, date(female_year, 7, 1)), + (i.Sex.FEMALE, date(female_year + 1, 1, 1)), + ] + for sex, birth in cohorts: + age = 65 if sex is i.Sex.MALE and birth < date(1913, 1, 2) else 62 + month = date(birth.year + age + 1, 12, 1) + person = i.Person(birth, sex=sex) + assert i.fully_insured_requirement(person, month) == required, ( + men, + women, + sex, + birth, + ) + tested += 1 + years = [int(event[:4])] + if "or prior" in event: + years.append(int(event[:4]) - 2) + if "or later" in event: + years.append(int(event[:4]) + 14) + for year in years: + person = i.Person( + date(1929, 7, 1), + sex=i.Sex.FEMALE, + death_date=date(year, 7, 1), + ) + assert ( + i.fully_insured_requirement(person, date(year, 12, 1)) + == required + ), (event, year) + tested += 1 + assert tested >= 150 + + def test_elapsed_years_from_birth_not_projection_entry(): person = i.Person(date(1980, 2, 2)) assert i.fully_insured_requirement(person, date(2026, 1, 1)) == 24 diff --git a/tests/test_track_b_insured_status_sources.py b/tests/test_track_b_insured_status_sources.py index d743c00e8..ef7c570ba 100644 --- a/tests/test_track_b_insured_status_sources.py +++ b/tests/test_track_b_insured_status_sources.py @@ -48,7 +48,7 @@ def source_text(source_id): # Each retained capture has a specific rule or documentary-purpose quote. -# The two exhibit shells are retained to pin exactly what is unavailable. +# The RS 00301.149 worksheet shell is retained to pin what is unavailable. RULE_QUOTES = { "poms_rs_00301_000_toc": [ "Retirement, Survivors and Disability Requirements", @@ -252,6 +252,14 @@ def source_text(source_id): "when the number of quarters in any period is an odd number, " "such number shall be reduced by one", ], + "poms_rs_00301_800_exhibit": [ + "Quarters of Coverage Requirements For Benefits Under Title II " + "of the Social Security Act", + "(If No Prior Period of Disability Established)", + "If birth on 1/1, use prior year.", + "If birth after 1/1/30, one QC needed for each year after the " + "year age 21 attained.", + ], "ssa_oact_qc": [ "No matter how high your earnings may be, you can not earn " "more than 4 QC's in one year.", @@ -263,7 +271,7 @@ def test_manifest_pins_every_capture(): document = manifest() assert document["schema_version"] == 1 sources = document["sources"] - assert len(sources) == 44 + assert len(sources) == 45 assert len({source["id"] for source in sources}) == len(sources) for source in sources: data = (SOURCES / source["file"]).read_bytes() @@ -519,13 +527,44 @@ def test_cfr_cohort_chart_is_complete_and_has_male_transition_rows(): assert [row[1] for row in chart if "Jan. 2, 191" in row[0]][:4] == [24] * 4 -def test_rs00301_800_chart_attachment_is_explicitly_unavailable(): +def test_rs00301_800_exhibit_text_pins_every_linked_attachment(): raw = (SOURCES / "poms_rs_00301_800.html").read_text() - assert "G-RS_00301.800-1.gif" in raw - assert "G-RS_00301.800-2.gif" in raw - assert "G-RS_00301.800-1.pdf" in raw + exhibit = next( + s + for s in manifest()["sources"] + if s["id"] == "poms_rs_00301_800_exhibit" + ) + served = { + body["url"].rsplit("/", 1)[-1] for body in exhibit["served_bodies"] + } + assert served == { + "G-RS_00301.800-1.pdf", + "G-RS_00301.800-1.gif", + "G-RS_00301.800-2.gif", + } + for name in served: + assert name in raw assert not tuple(SOURCES.glob("*.gif")) + assert not tuple(SOURCES.glob("*.pdf")) case = next( e for e in registry()["examples"] if e["id"] == "poms_800_exhibit" ) - assert case["coverage"] == "missing_attachment" + assert case["coverage"] == "table_differential" + + +def test_rs00301_800_pdf_footnote_misprints_the_1913_male_age_65_cohort(): + """The PDF's footnote says 1/2/31; its GIF rendering and the CFR say 1913. + + The image rendering (G-RS_00301.800-2.gif, pinned in served_bodies) + prints "born before 1/2/13", and the exhibit's own table splits its male + and female columns at 1913. 20 CFR 404.132(b) ties the male rule to men + born before January 2, 1913. The implementation follows the CFR. + """ + assert ( + "The determining age for men born before 1/2/31 is age 65." + in source_text("poms_rs_00301_800_exhibit") + ) + assert "1910-1913 1913 1975 24" in source_text("poms_rs_00301_800_exhibit") + assert "If you are a man born before January 2, 1913" in source_text( + "ecfr_20cfr404_subpart_b" + ) From f865bb546d4ec9764dd151a1597385ec49591f75 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Fri, 23 Oct 2026 10:24:53 -0400 Subject: [PATCH 05/46] Recount test tiers after the RS 00301.800 exhibit tests Co-Authored-By: Claude Opus 5.5 --- tests/README-tiers.md | 4 ++-- tests/tier_counts.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/README-tiers.md b/tests/README-tiers.md index 9af8d40c9..cff0d3b2e 100644 --- a/tests/README-tiers.md +++ b/tests/README-tiers.md @@ -39,9 +39,9 @@ pytest --collect-only -q -m oracle_policyengine | tail -1 | Tier | Tests at HEAD | |---|---:| -| `unit` | 19,321 | +| `unit` | 19,324 | | `artifact` | 4,253 | | `integration_psid` | 1,450 | | `reproduction_legacy` | 520 | | `oracle_policyengine` | 308 | -| **Total** | **25,852** | +| **Total** | **25,855** | diff --git a/tests/tier_counts.json b/tests/tier_counts.json index 6159e8abf..3edacbc59 100644 --- a/tests/tier_counts.json +++ b/tests/tier_counts.json @@ -1,7 +1,7 @@ { "schema_version": 1, "counts": { - "unit": 19321, + "unit": 19324, "artifact": 4253, "integration_psid": 1450, "reproduction_legacy": 520, From 74da853b1b0b930de01af545a0e327f3afd257c4 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sun, 25 Oct 2026 05:55:48 -0400 Subject: [PATCH 06/46] Separate medical onset from an established period of disability Round 1 of the independent review found that a declared disability onset froze the fully insured elapsed-year count and anchored the disability test to the onset quarter. A period of disability exists only after an application and five months (42 U.S.C. 416(i)(2)(A)-(B); 20 CFR 404.320(b)), and it begins on the onset day only if the worker is insured then, otherwise on the first day of the first later qualifying quarter (416(i)(2)(C); 404.321(a)). So: - Onset alone no longer removes elapsed years (404.110). The current period's establishment is declared, with provenance. - The disability test scans the quarters from onset to the query and uses each candidate year's fully insured endpoint (404.131(a), 404.132). A later qualifying quarter now counts. - Currently insured excludes every established period intersecting the 13-quarter window, including the event's own (404.120(b), RS 00301.110). The old contract assertion pinned the misreading. - Count bounds with a switching witness use a sound envelope. It also takes the open-population lane's rev 10 needs. Prior periods, the current period and section 214(c) applicability carry OBSERVED / CONVENTION_FILLED / UNKNOWN provenance, with UNKNOWN as the default. Unknown facts are bounded, or refused by name: unknown_prior_disability_periods_decide_status, unknown_current_disability_period_decides_status and sspa211_applicability_unknown. The no-periods lower bound rests on 404.320(a) and 404.130(f). Adds 20 CFR 404.315, 404.320 and 404.321 captures. Moves the mutation report to docs/design/track_b_insured_status_mutations.json, next to its design note. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 268 +++- .../track_b_insured_status_mutations.json | 1399 +++++++++++++++++ .../track_b/insured_status.py | 525 ++++++- .../data/track_b/insured_status_examples.yaml | 28 + .../insured_status_mutation_checks.json | 418 ----- .../track_b/insured_status_sources/README.md | 26 +- .../ecfr_20cfr404_315.xml | 14 + .../ecfr_20cfr404_320.xml | 12 + .../ecfr_20cfr404_321.xml | 12 + .../insured_status_sources/manifest.json | 30 + ...ack_b_gross_benefits_fix_round_13_audit.py | 18 +- ...b_gross_benefits_fix_round_15_arguments.py | 9 +- tests/test_track_b_input_schema.py | 9 +- tests/test_track_b_insured_status.py | 317 +++- tests/test_track_b_insured_status_contract.py | 120 +- ...test_track_b_insured_status_fix_round_2.py | 775 +++++++++ .../test_track_b_insured_status_mutations.py | 27 + ...ck_b_insured_status_period_declarations.py | 177 +++ tests/test_track_b_insured_status_sources.py | 49 +- 19 files changed, 3661 insertions(+), 572 deletions(-) create mode 100644 docs/design/track_b_insured_status_mutations.json delete mode 100644 tests/data/track_b/insured_status_mutation_checks.json create mode 100644 tests/data/track_b/insured_status_sources/ecfr_20cfr404_315.xml create mode 100644 tests/data/track_b/insured_status_sources/ecfr_20cfr404_320.xml create mode 100644 tests/data/track_b/insured_status_sources/ecfr_20cfr404_321.xml create mode 100644 tests/test_track_b_insured_status_fix_round_2.py create mode 100644 tests/test_track_b_insured_status_mutations.py create mode 100644 tests/test_track_b_insured_status_period_declarations.py diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index a6a79dfbe..e4cb577c5 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -4,7 +4,8 @@ Verification class: **statutory conformance**. Version: `track-b-insured-v1`. Admitted scope: invented declarations and published statutory examples only. There is no population, behavioral, claiming-hazard, or forecast claim. The governing reference is Act sections 213, 214, 216(i), 223(c)(1), -20 CFR part 404 subpart B, and POMS RS 00301. Sources are captured under +20 CFR part 404 subpart B and sections 404.315, .320, .321, and POMS +RS 00301. Sources are captured under `tests/data/track_b/insured_status_sources/`; the example registry explicitly separates reproduced computations from refused and unavailable examples. @@ -39,16 +40,19 @@ onset, and disability-period boundaries retain their actual days. Age is attained on the day before the birthday (404.102). Integer quarter IDs in windows and assignments are `4 * year + quarter - 1`, with quarter 1–4. Status at a hypothetical entitlement/onset month takes effect on the first -day of its calendar quarter; it can cease at the next quarter boundary or -at January's change in the fully insured requirement. This is an insured +day of its calendar quarter. A quarter's ordinary predicate can cease at +the next quarter boundary or January's elapsed-year change. With declared +continuous medical disability, the disability decision retains the first +qualifying quarter through the query (404.131(a)). This is an insured status calculation, not entitlement, medical disability, or a payment. Currently insured uses the supplied death date, RIB entitlement month, or most recent DIB entitlement month when available; any qualifying event suffices. With none supplied it tests a hypothetical event in the query quarter (214(b); RS 00301.110). Actual event dates are retained in later queries; an emigrant with no entitlement event continues on the query clock. -Only disability periods ending before a historical event are prior periods -for its13-quarter window; the event’s own later-ending period is not excluded. +Every established period intersecting that event's 13-quarter window is +considered, including a period containing or extending beyond the event. +The credited first and last quarters remain eligible (404.120(b); RS .110). `Person` declares `birth_date`, optional `sex` (`Sex.MALE` or `Sex.FEMALE`, required for pre-January-2-1913 cohorts), optional `death_date`, optional @@ -58,18 +62,85 @@ required for pre-January-2-1913 cohorts), optional `death_date`, optional `rib_entitlement_month` and `dib_entitlement_month` (the most recent DIB entitlement). Supplied entitlement months must be within the lifetime and no later than the query. An SSN assignment cannot precede birth. An alien -worker must declare either an assignment date or `ssn_never_assigned=True`; -supplying both is an input error. Never-assigned alien workers and those -whose first assignment was on or after January 1, 2004 receive the named -SSPA 211 refusal (RS 00301.102); missing SSN facts do not silently imply -that the additional requirement is satisfied. +worker may supply an assignment date or `ssn_never_assigned=True`; +supplying both is an input error. These legacy facts derive known section +214(c) applicability. Alternatively the caller declares `sspa211_applies` +with `sspa211_provenance` and optional `sspa211_convention_id`. Applicability +is decided before the additional requirement is tested. RS 00301.102 B.1 +exempts workers whose first SSN was assigned before January 1, 2004, +including nonwork SSNs. B.3 expressly includes workers not yet assigned an +SSN in their true identity. B.4.b permits specified work-authorized workers +without an SSN to meet the requirement; it does not exempt all unassigned +workers. Known applicability retains the named unimplemented SSPA 211 +adjudication refusal. Unknown applicability returns a QC-only uninsured +answer when it is false either way, flagged as decided despite unknowns; +otherwise it raises `sspa211_applicability_unknown`. For example, zero +lifetime QCs cannot insure a worker whether section 214(c) applies or not. A `DisabilityPeriod` declares `start`, `end`, and `special_insured`: the latter is an adjudicated fact that the earlier period qualified only under the special young-worker test. -Periods must not overlap calendar quarters. Onset may be later within the -query month, but not in a later month. A nonblind declared onset anchors the -disability witness; this preserves the onset test without claiming to -adjudicate the waiting period or a continuous disability freeze (.120). +Periods must not overlap calendar quarters. The ordered period sequence has +`prior_disability_periods_provenance` and optional +`prior_disability_periods_convention_id`; an observed empty sequence +explicitly means no established periods. The default provenance is +`UNKNOWN`, which must contain no periods and never silently means none. + +`disability_onset` means medically disabled continuously from that day +through the query month; the rule does not adjudicate recovery. Onset may +be later within the query month, but not in a later month. Onset alone +never establishes a period or freezes elapsed years. With an onset, the +caller must explicitly declare `current_disability_period_provenance` and +`current_disability_period_established`: `True` or `False` for known facts, +or `None` with explicit `UNKNOWN`. Omitting this declaration is an input +error. `current_disability_period_convention_id` accompanies a convention. +The same canonical `EarningsProvenance` enum applies to all three factual +declarations: `OBSERVED`, `CONVENTION_FILLED` with a nonempty identifier, +or `UNKNOWN` without a value. The rule supplies no convention internally. + +An established current period begins at medical onset if insured then, +otherwise on the first day of the first later insured quarter +(416(i)(2)(C); 404.321(a)). Establishment additionally requires an +application and the statutory duration or DIB-entitlement alternative +(416(i)(2)(A)-(B); 404.320(b)); the caller's declaration supplies these +administrative facts. A known established period with no possible insured +disabled quarter is invalid. Its start is derived from the supplied QC +history, then its years are excluded like any other established period. +On the ordinary supported QC surface, this includes known current +establishment with fewer than six maximum feasible lifetime QCs even when +prior periods are UNKNOWN: 404.130(a) +requires fully insured status, and 404.110(b)(1) says, "You need at least +6 QCs but not more than 40 QCs to be fully insured." Excluding periods +cannot supply the missing credits. When declared QC facts prove this +contradiction, the input error precedes coverage refusals, including +foreign-credit, specialist, SSPA-applicability, and period-uncertainty +refusals. Other military, railroad, deemed, and transitional declarations +retain their specialist refusals; no alternate-credit regime is adjudicated. +When prior periods are UNKNOWN, favorable disregard of every period can +still decide the Boolean status even if the current period's derived +start is uncertain. `current_disability_period_start` is then `None`, and +`unknown_facts` includes `current_disability_period_start`; the established +fact itself remains known. If the disregard treatment already qualifies +at medical onset, onset is the certain start. Disregard is a permitted +statutory treatment, not an assertion that a known period never existed. + +The disability test scans the onset quarter through the query quarter. +Each candidate's 20/40 or special window ends in that candidate quarter, +and its fully insured prerequisite ends elapsed years before the +candidate's year (416(i)(3); 423(c)(1)(A)-(B); 404.130-.132). This permits a +later qualifying quarter for blind and nonblind workers. For example, +birth February 2, 2000, onset January 15, 2022, four QCs in 2021 and two +in 2022 produce five assignable recent QCs at 2022Q1 and six at 2022Q2. +The April query is disability insured with a 2022Q2 witness. The window +endpoint therefore follows the qualifying disabled quarter, rather than +remaining permanently at medical onset. + +The waiting-period clause cannot produce an earlier elapsed-year endpoint +in this interface. Section 404.315(a)(4) states, "The 5-month waiting period +begins with a month in which you were both insured for disability and +disabled." Such a month cannot precede the first insured disabled quarter +that begins the period under 404.321(a). Filing can delay the waiting +period, but cannot move it before that first qualifying quarter. The +established-current-period property below executes this ordering. Every year from `max(1937, birth_date.year)` through the earliest of query, death, or coverage-end year must appear exactly once. Mapping iteration @@ -114,17 +185,31 @@ nonempty declaration receives `totalization_credits_unsupported`. (unrequested decisions are `None`), `qcs_by_year` count ranges, a canonical lower-bound `assigned_quarters` mapping, `unknown_years`, `convention_years`, `decided_despite_unknowns`, `dli`, `month`, and `version`. +It also reports `current_disability_period_start`, `unknown_facts`, and +the identifiers in `convention_facts` separately from earnings provenance. Each `StatusDecision` supplies `insured`, `qc_count_lower`, `qc_count_upper`, `required`, `window`, `assigned_quarters`, and `rule`, with corresponding `upper_required`, `upper_window`, `upper_assigned_quarters`, and `upper_rule`. It also reports the fully insured prerequisite separately through `fully_required`, `upper_fully_required`, `fully_qc_count_lower`, and -`fully_qc_count_upper`. Thus a disability witness can show 20 recent QCs +`fully_qc_count_upper`, plus `qualifying_quarter` and +`upper_qualifying_quarter` for the first successful disabled quarter in +each earnings-bound world. Thus a disability witness can show 20 recent QCs and still be uninsured because its duration-of-work requirement is not met. The low and high witnesses each optimize assignment for that particular test. They need not have the same assignment or prior-period treatment. The per-year QC mapping uses the disability-excluded context; the witness identifies credits actually used if disregarding the periods is favorable. +Witness fields describe selected computations; their endpoint counts are +not automatically guaranteed envelopes. A favorable treatment or endpoint +witness can switch as unknown QCs rise, reducing a selected count. Where +unknown years interact with periods or an onset, and where period facts +are unknown, count bounds use zero through the maximum feasible lifetime +QCs before period exclusions. Multiple historical event witnesses can +also switch as unknown credits rise, so they use the same envelope. +This universal envelope contains every +concrete recent and fully-prerequisite count. Complete observed inputs +retain exact counts. No narrower selected-witness bound is claimed. If either bound differs on a requested Boolean status, the call raises the sealed `unknown_earnings_years_decide_status` refusal. If both agree, the @@ -134,6 +219,22 @@ another test cannot hide an otherwise decidable answer. No convention is inferred. Every convention-filled year and its identifier is disclosed even if it is outside the decisive recent-work window. +For unknown prior or current establishment facts, ordinary covered-credit +status under favorable disregard of those periods is a sound Boolean +lower bound, including when current establishment is known but its start +depends on unknown prior periods. Section +404.130(f) permits favorable all-period disregard for the disability +window; 404.320(a) supplies the broader rule: "If benefits payable on your +earnings record would be denied or reduced because of a period of +disability, the period of disability will not be taken into consideration." +Railroad and noncreditable military credits remain refused, preserving +RS .120's exception. A true lower bound therefore decides true. For valid +declarations, fewer +than six maximum feasible lifetime QCs decides false. Otherwise unknown +periods may change a false result, so the rule refuses by name. Current +establishment does not change the disability qualification scan that must +prove its start; using its own exclusion would be circular. + `DLIRange.lower` and `.upper` are last-quarter-end dates; `None` is the bottom bound meaning no insured quarter. Without an exit declaration, this is DLI **through the query**, with `right_censored=True` if still insured; @@ -145,6 +246,25 @@ coverage is frozen and the search can continue to the quarter before FRA attainment, or death if earlier (RS 00301.148). DLI itself can remain a range when the requested current statuses agree. Unknown future earnings must not be inferred from this range or from a censored result. +With unknown section214(c) applicability, a decided false current status +does not prove that the additional fully insured requirement was met at a +historical witness (214(c); RS .102). The conservative DLI lower bound is +`None`, while the upper bound retains the QC-only date, including any +period and earnings uncertainty. For example, birth February 2, 1980, +20 QCs in 2000–2004, and a January 2026 query give false current statuses +but a QC-only DLI of December 31, 2009. Unknown applicability reports +`None` through that date; exemption can recover the exact date. This is +pinned by `test_unknown_sspa_applicability_does_not_block_qc_only_uninsured_result` +and `test_unknown_sspa_applicability_preserves_qc_impossibility`. +With unknown established periods the all-periods-disregarded DLI supplies +a lower bound, +while the upper bound is the allowed query/FRA/death horizon; an exit +already reached uses the frozen-coverage FRA/death horizon. This can be a +broad range even when status is decided. With known prior-period history, +a declared ongoing established current period and an exit already reached, +a future DLI +would depend on recovery beyond the query, which is unobserved. That +configuration receives `ongoing_disability_period_dli_horizon_unsupported`. ## Exact rules and supported configurations @@ -156,14 +276,14 @@ must not be inferred from this range or from a censored result. | Calendar-year SE | At least $400 gives four QCs from 1951; below $400 contributes only to the applicable maximum-earnings rule (RS .340/.345). | | Agriculture | 1955–77 annual $100 increments, up to four, added to uncredited quarters. Covered 1951–54 agricultural wages must already be included in quarterly covered wages (RS .320/.325). | | Flexible assignment | Assign annual credits to whichever allowed quarters favor each test. Distinct tests expose distinct witnesses (404.143/.145; RS .230). | -| Fully insured | One QC per elapsed year after 1950 or age 21 year, minimum six, maximum 40; stop before query, age 62, death, or applicable onset year; exclude years partially or wholly in a used disability period (214(a);404.110;RS .105). | +| Fully insured | One QC per elapsed year after 1950 or age 21 year, minimum six, maximum 40; stop before query, age 62, or death. Exclude only years partially or wholly in an established period; medical onset alone never caps elapsed years (214(a);404.110;RS .105). | | Early male retirement cohorts | Before January 2, 1911 use age 65; January 2, 1911–January 1, 1913 use 1975, subject to earlier query/death (404.110; RS .105). | | Early male disability prerequisite | For every man born before January 2, 1913, the disability-specific fully insured elapsed-year endpoint is 1975 or the earlier relevant disability year (404.132(b)). It can differ from the retirement fully insured decision. | -| Currently insured | Six QCs within 13 counted quarters ending with an actual declared death/RIB/DIB event, or the hypothetical query event (214(b);404.120;RS .110). | -| Disability | Fully insured plus 20 QCs in 40 counted quarters (223(c)(1);216(i)(3);404.130;RS .120/.130). | +| Currently insured | Six QCs within 13 counted quarters ending with an actual declared death/RIB/DIB event, or the hypothetical query event. Every intersecting established period can extend the window, including the event's own period (214(b);404.120;RS .110). | +| Disability | Scan onset through query for the first candidate quarter with the candidate-year fully insured prerequisite plus 20 QCs in 40 counted quarters, or a special rule (223(c)(1);216(i)(3);404.130-.132;RS .120/.130). | | Young worker | Before the age 31 attainment quarter: half the quarters after the age 21 quarter, dropping an odd remainder, minimum six. Fewer than 12 elapsed quarters uses 6/12; age 24 attainment quarter still uses 6/12 (404.130(c);RS .140). | | Subsequent disability | With declared earlier special insured status, the special test can apply after 31, up to 20/40. Prior periods are all used or all disregarded, whichever admits insured status; endpoints count in windows only if QCs (404.130(f);RS .120/.147). | -| Blindness | Fully insured only, with elapsed years continuing until the qualifying QC year if onset itself was not insured (RS .150). | +| Blindness | Only the fully insured prerequisite, evaluated at each candidate disabled quarter; it can first qualify after medical onset, as can nonblind status (404.130(e),404.131;RS .150). | | DLI | Latest fully-and-disability-insured quarter end, with explicit query censoring or frozen-exit horizon and FRA cap (RS .148). | For prior disability periods, only years containing their endpoint quarters @@ -190,10 +310,15 @@ a subclass of the shared `FamilyConfigurationUnsupported`. | Trigger | Reason code | | --- | --- | | Unknown-year bounds decide a requested status differently | `unknown_earnings_years_decide_status` | +| Unknown prior periods may change a requested status | `unknown_prior_disability_periods_decide_status` | +| Unknown current establishment may change a requested status | `unknown_current_disability_period_decides_status` | +| Unknown section 214(c) applicability may change a requested status | `sspa211_applicability_unknown` | +| Standalone requirement helper needs coverage history to derive a declared current period start | `current_disability_period_requires_history` | +| Ongoing established current period, known prior-period history, and a frozen-exit DLI horizon beyond query | `ongoing_disability_period_dli_horizon_unsupported` | | Any foreign totalization credits | `totalization_credits_unsupported` | | Declared deemed nonprofit/veteran fully insured path | `deemed_fully_insured_unsupported` | | Declared transitional insured path | `transitional_insured_unsupported` | -| Alien SSN never assigned, or first assigned on/after January 1, 2004 | `alien_worker_sspa211_unsupported` | +| Known section 214(c) applicability needs unimplemented work-authorization/visa adjudication, including never-assigned alien SSNs | `alien_worker_sspa211_unsupported` | | Railroad or military credits | `railroad_credits_unsupported`, `military_credits_unsupported` | | Medicare-qualified government employment | `medicare_government_employment_unsupported` | | Earned-basis wages or pre1956 alternate disability | `earned_basis_unsupported`, `disability_before_1956_unsupported` | @@ -247,10 +372,15 @@ properties. The final execution report lists exact commands and results. - Excluding disability interiors never adds a QC and preserves eligible endpoints: `test_disability_exclusion_never_adds_qc` and the public `test_property_disability_period_exclusion_never_adds_qcs`. -- Every insured status and DLI are monotone when a QC is added; disability - insured implies fully insured: +- With fixed declared disability-period boundaries, insured status and DLI + are monotone when a QC is added; disability + insured implies the fully insured prerequisite at its qualifying + quarter. Without an established period, the query's later old-age + requirement can differ: `test_property_status_and_dli_monotone_in_quarters` and - `test_property_subsequent_special_and_dli_monotonic`. + `test_property_subsequent_special_and_dli_monotonic`. The separate + intended query-fully/onset-disability distinction is pinned by + `test_unknown_current_period_refuses_when_establishment_changes_full_status`. - Unknown status, count, and DLI bounds contain every concrete filling or the rule refuses: `test_property_unknown_bounds_cover_every_filling`, `test_unknown_bounds_with_prior_disability_period`, and @@ -272,6 +402,28 @@ properties. The final execution report lists exact commands and results. `test_exact_sei_allocation_conserves_income`. This is private worked arithmetic, not an expansion of the public supported configuration. +Round 2 adds these executed invariants and interface properties: + +| Invariant | Hypothesis test | +| --- | --- | +| Declared continuous-disability status equals the disjunction of plain candidate-quarter predicates from onset through query; the first qualifying witness and window endpoint agree. DLI reaches the onset quarter exactly when this scan succeeds. Derived period start is onset day or the first later qualifying quarter's first day; no waiting period can start earlier. | `test_continuous_onset_status_and_dli_equal_plain_quarter_scan` | +| The same scan, first-witness, and DLI identity holds with an established prior period and its favorable treatment. | `test_continuous_onset_with_prior_period_matches_plain_predicate_scan` | +| Recent and fully-prerequisite QC envelopes contain every concrete unknown-year filling even when periods are present and the selected witness switches; supported Boolean results agree with every filling. | `test_unknown_recent_and_fully_counts_contain_concrete_period_fillings` | +| Supported statuses and DLI bounds with UNKNOWN prior/current periods contain all generated concrete established-period fillings; favorable no-period lower bounds never overstate status or DLI. | `test_unknown_period_status_and_dli_bounds_contain_concrete_fillings` | +| Replacing observed fact provenance with convention-filled provenance and identifiers changes no status or DLI; all identifiers remain disclosed. | `test_declared_fact_provenance_preserves_computed_status` | +| UNKNOWN section 214(c) applicability preserves decided false current statuses and discloses that unknown fact. Historical DLI is bounded by None through the QC-only upper date; the envelope contains the exempt filling even with old insured work histories. A true current QC predicate requires the named applicability refusal. | `test_unknown_sspa_applicability_preserves_qc_impossibility` | + +The reviewer's examples separately pin onset without establishment, +later-quarter qualification, the event's own established period, and the +24/26 endpoint-count counterexample containing a concrete count of 23: +`test_medical_onset_alone_never_freezes_fully_insured_elapsed_years`, +`test_continuous_disability_can_first_qualify_after_medical_onset`, +`test_currently_insured_excludes_period_containing_dib_event`, and +`test_unknown_prerequisite_count_bounds_contain_witness_switch_fillings`. +The original assertion excluding an event's own later-ending period pinned +a source misreading. Correcting it implements 404.120(b)'s exclusion of +every intersecting established period. + Boundary examples additionally pin actual-event windows and future-exit censoring: `test_currently_insured_uses_death_quarter_after_death`, `test_currently_insured_preserves_actual_entitlement_event`, @@ -285,6 +437,11 @@ disability prerequisite is pinned by The YAML registry records source literals, expectations, coverage labels, and any divergence. Source tests hash every capture and verify every quoted rule and every example figure verbatim after documented text normalization. +The manifest retains 48 captures. The registry contains 48 entries: 27 +computed cases, 12 named refusals, three source-rule divergences, one +source ambiguity, three table differentials, and two administrative +inventory entries. Inventory and refused entries are not claimed as +reproduced statutory calculations. The QC table matches POMS 1978–2026 and OACT 1978–2027 exactly. The repository NAWI bundle reproduces every computable increment 1979–2026 with zero arithmetic tolerance. OACT 2027 gives $250 × $72,800.33 / $9,226.48 = @@ -299,6 +456,21 @@ needs 14 for fully insured in 1990, and has DLI June 30, 1990 by assigning 1980's two annual credits to Q3/Q4. RS .150 Calvin Hill needs seven QCs in 1986; the sixth in Q1 is insufficient and the seventh makes him insured April 1, 1986. These calculations are pinned directly in the public tests. +The added Sam White registry case quotes the source's statement that he +may become insured later. The source supplies no later history or date; +the explicitly invented completion of three QCs in each of 1983 and 1984 +gives five assignable QCs at 1984Q2 and six at 1984Q3. This demonstrates the +published later-status rule without presenting the invented date as a +published numerical result. + +The reviewer's uninsured-onset case has birth February 2, 1980, medical +onset January 15, 2007, no established period, four 2008 QCs and two 2009 +QCs. At April 2009 the old-age/survivor elapsed years 2002–2008 require +seven QCs, so six do not insure. Medical onset cannot replace that seven +with six. The current-period example has DIB entitlement July 2004 inside +an established January–December 2004 period and three QCs in each of 2001 +and 2002. Excluding the event's own period extends the 13-quarter window +to 2000Q4–2003Q4 and yields six QCs, hence currently insured. RS .800's exhibit is a PDF and two GIF renderings of the same table. Its text was extracted from the PDF with pdftotext; the PDF and both GIFs are @@ -318,9 +490,53 @@ if $10,900 meant net earnings before that ceiling. Tests execute both readings; both give three QCs. The public short-year path remains refused. RS .345 prints an impossible “after 1975 and before 1975” SE fiscal bracket; the calendar 1975 maximum of $14,100 is independently clear in its wage table. No fiscal interpretation is silently inferred. -The subsequent-disability examples are also checked against the operative -endpoint and all-periods-disregarded rules; the final report records any -executed divergence and the exact supporting text for review. +The subsequent-disability examples retain both the source's printed result +and the operative regulation. RS .140 example 6 prints 18 elapsed +quarters/nine required QCs; retaining credited endpoint quarters under +404.130(f) gives 20/10 with 16 available, still insured. RS .147 example 3 +prints 33 elapsed/16 required/eight available; favorable annual assignment +to the 1978Q4 endpoint gives 34/17/nine, still uninsured. RS .147 example 2 +says John "requires and has 16" although the full record contains 18; +its statement that two additional QCs would reach 20 confirms the latter. + +## Readings for the orchestrator + +These readings apply the statute first, then the regulation, with agency +guidance resolving remaining questions. They do not request an additional +reading from Max. + +For RS .140 example 9, the printed conclusion says, "Sam requires 8 QC's +but has only 7 QC's and does not meet insured status as of 5/93." Section +404.130(f) instead says, "However, we will count all the quarters in the +prior period of disability established for you if by doing so you would +be entitled to benefits or the amount of the benefit would be larger." +RS .120 B.1.b also requires all prior periods to be used or all +disregarded. Disregarding the freeze gives 20 QCs in the 40-quarter +1983Q3–1993Q2 window and the fully insured prerequisite of eight, so the +implemented result is insured. The printed used-freeze treatment has 17 +elapsed quarters, eight required, and seven available. An otherwise +payable invented $1,000 monthly benefit would differ by $1,000 versus +zero under these insurance answers; this module computes no payment. + +The credited-endpoint and favorable-assignment readings above are retained: +404.130(f) keeps an endpoint if it is a QC, and RS .230 permits favorable +annual assignment. They change intermediate counts in RS .140 example 6 +and RS .147 example 3, but neither example's insured conclusion. The +short-tax-year $10,900 versus $10,800 reading remains a named public +refusal; both readings give three QCs but differ by $100 in allocated +earnings. The exit-year annual-count cap remains an explicit interface +convention, not a statutory emigration exclusion. + +Medical onset versus administrative establishment and the event's own +period are corrections required by 416(i)(2), 404.110(c), 404.120(b), and +404.320-.321. The never-assigned-SSN applicability text in RS .102 B.3 +also controls over the coordinator's reported blanket exemption; B.4.b's +work-authorized exception concerns satisfying the requirement. Known +applicable cases remain refused until that adjudication is implemented. + +Mutation checks are recorded in +[`track_b_insured_status_mutations.json`](track_b_insured_status_mutations.json). +Every recorded implementation mutation was caught and reverted. ## Not in scope diff --git a/docs/design/track_b_insured_status_mutations.json b/docs/design/track_b_insured_status_mutations.json new file mode 100644 index 000000000..dacddfd45 --- /dev/null +++ b/docs/design/track_b_insured_status_mutations.json @@ -0,0 +1,1399 @@ +{ + "verification_class": "statutory_conformance", + "scope": "Invented and captured statutory cases only; no population, behavioral or forecast claim.", + "qc_mutations": [ + { + "name": "qc_cap_4_to_3", + "before": "return min(4, (wages + self_employment) // QC_AMOUNTS[year])", + "after": "return min(3, (wages + self_employment) // QC_AMOUNTS[year])", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary", + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1978]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1979]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1980]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1981]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1982]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1983]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1984]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1985]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1986]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1987]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1988]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1989]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1990]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1991]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1992]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1993]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1994]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1995]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1996]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1997]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1998]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1999]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2000]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2001]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2002]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2003]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2004]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2005]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2006]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2007]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2008]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2009]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2010]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2011]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2012]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2013]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2014]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2015]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2016]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2017]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2018]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2019]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2020]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2021]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2022]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2023]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2024]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2025]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2026]", + "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2027]" + ], + "summary": [ + "50 failed, 150 passed in 15.27s" + ], + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/track-b-insured-psid", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/track-b-insured-epuf", + "PYTHONPATH": "$PWD/src:$PWD", + "PYTHONDONTWRITEBYTECODE": "1" + }, + "restored": true + }, + { + "name": "round_drop_half_tie", + "before": "rounded = ((indexed + 5) // 10) * 10", + "after": "rounded = ((indexed + 0) // 10) * 10", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_qc.py::test_qc_amount_ties_round_up", + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_qc.py::test_qc_amount_ties_round_up[delta1-260]", + "FAILED tests/test_track_b_insured_status_qc.py::test_qc_amount_ties_round_up[delta2-260]" + ], + "summary": [ + "2 failed, 1 passed in 6.57s" + ], + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/track-b-insured-psid", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/track-b-insured-epuf", + "PYTHONPATH": "$PWD/src:$PWD", + "PYTHONDONTWRITEBYTECODE": "1" + }, + "restored": true + }, + { + "name": "wage_50_inclusive_to_strict", + "before": "if wages >= 50", + "after": "if wages > 50", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary", + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1937]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1938]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1939]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1940]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1941]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1942]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1943]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1944]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1945]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1946]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1947]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1948]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1949]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1950]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1951]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1952]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1953]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1954]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1955]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1956]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1957]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1958]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1959]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1960]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1961]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1962]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1963]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1964]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1965]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1966]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1967]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1968]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1969]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1970]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1971]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1972]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1973]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1974]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1975]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1976]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1977]" + ], + "summary": [ + "41 failed in 16.30s" + ], + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/track-b-insured-psid", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/track-b-insured-epuf", + "PYTHONPATH": "$PWD/src:$PWD", + "PYTHONDONTWRITEBYTECODE": "1" + }, + "restored": true + }, + { + "name": "sei_400_inclusive_to_strict", + "before": "or self_employment >= 400", + "after": "or self_employment > 400", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary", + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1951]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1952]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1953]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1954]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1955]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1956]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1957]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1958]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1959]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1960]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1961]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1962]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1963]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1964]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1965]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1966]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1967]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1968]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1969]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1970]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1971]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1972]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1973]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1974]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1975]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1976]", + "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1977]" + ], + "summary": [ + "27 failed in 9.66s" + ], + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/track-b-insured-psid", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/track-b-insured-epuf", + "PYTHONPATH": "$PWD/src:$PWD", + "PYTHONDONTWRITEBYTECODE": "1" + }, + "restored": true + }, + { + "name": "disability_exclude_first_endpoint", + "before": "start < quarter < end", + "after": "start <= quarter < end", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_qc.py::test_death_future_exit_and_disability_endpoint_exclusions", + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_qc.py::test_death_future_exit_and_disability_endpoint_exclusions" + ], + "summary": [ + "1 failed in 7.23s" + ], + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/track-b-insured-psid", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/track-b-insured-epuf", + "PYTHONPATH": "$PWD/src:$PWD", + "PYTHONDONTWRITEBYTECODE": "1" + }, + "restored": true + }, + { + "name": "assignment_maximize_to_minimize", + "before": "-len(target.intersection(candidate))", + "after": "len(target.intersection(candidate))", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_qc.py::test_rs00301_230_henry_and_325_john_retroactive_assignment", + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_qc.py::test_rs00301_230_henry_and_325_john_retroactive_assignment" + ], + "summary": [ + "1 failed in 6.27s" + ], + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/track-b-insured-psid", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/track-b-insured-epuf", + "PYTHONPATH": "$PWD/src:$PWD", + "PYTHONDONTWRITEBYTECODE": "1" + }, + "restored": true + }, + { + "name": "agricultural_increment_100_to_200", + "before": "agricultural_wages // 100", + "after": "agricultural_wages // 200", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_qc.py::test_rs00301_320_jane_agricultural_example", + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_qc.py::test_rs00301_320_jane_agricultural_example" + ], + "summary": [ + "1 failed in 5.11s" + ], + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/track-b-insured-psid", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/track-b-insured-epuf", + "PYTHONPATH": "$PWD/src:$PWD", + "PYTHONDONTWRITEBYTECODE": "1" + }, + "restored": true + }, + { + "name": "gift_maximum_inclusive_to_strict", + "before": "wages + self_employment >= _annual_wage_limit(year)", + "after": "wages + self_employment > _annual_wage_limit(year)", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs", + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1937-1950-3000]", + "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1951-1954-3600]", + "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1955-1958-4200]", + "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1959-1965-4800]", + "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1966-1967-6600]", + "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1968-1971-7800]", + "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1972-1972-9000]", + "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1973-1973-10800]", + "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1974-1974-13200]", + "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1975-1975-14100]", + "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1976-1976-15300]", + "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1977-1977-16500]" + ], + "summary": [ + "12 failed in 3.60s" + ], + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/track-b-insured-psid", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/track-b-insured-epuf", + "PYTHONPATH": "$PWD/src:$PWD", + "PYTHONDONTWRITEBYTECODE": "1" + }, + "restored": true + } + ], + "status_mutations": { + "file": "src/populace_dynamics/track_b/insured_status.py", + "sha256_before": "b6bf989787bd465e080a435d77a178cee9ef861535eac190ab7fca9bd1033fc8", + "mutations": [ + { + "name": "fully_minimum_6_to_5", + "before": "return min(40, max(6, elapsed))", + "after": "return min(40, max(5, elapsed))", + "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status.py -k test_fully_six_qcs_minimum", + "exit_code": 1, + "seconds": 49.08, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status.py::test_fully_six_qcs_minimum[5-False]", + "FAILED tests/test_track_b_insured_status.py::test_fully_six_qcs_minimum[6-True]" + ], + "output": "FF [100%]\n=================================== FAILURES ===================================\n_____________________ test_fully_six_qcs_minimum[5-False] ______________________\n\ncount = 5, expected = False\n\n @pytest.mark.parametrize(\"count,expected\", [(5, False), (6, True)])\n def test_fully_six_qcs_minimum(count, expected):\n person = i.Person(date(2000, 2, 2))\n result = compute(\n person,\n date(2026, 12, 1),\n {2025: 4, 2026: count - 4},\n test=i.InsuredTest.FULLY,\n )\n> assert result.fully.required == 6\nE AssertionError: assert 5 == 6\nE + where 5 = StatusDecision(insured=True, qc_count_lower=5, qc_count_upper=5, required=5, window=(8000, 8001, 8002, 8003, 8004, 800... 8101, 8102, 8103, 8104, 8105, 8106, 8107), upper_assigned_quarters=(8100, 8101, 8102, 8103, 8104), upper_rule='fully').required\nE + where StatusDecision(insured=True, qc_count_lower=5, qc_count_upper=5, required=5, window=(8000, 8001, 8002, 8003, 8004, 800... 8101, 8102, 8103, 8104, 8105, 8106, 8107), upper_assigned_quarters=(8100, 8101, 8102, 8103, 8104), upper_rule='fully') = InsuredStatus(version='track-b-insured-v1', month=datetime.date(2026, 12, 1), fully=StatusDecision(insured=True, qc_co...101, 8102, 8103), 2026: (8104,)}), unknown_years=(), convention_years=mappingproxy({}), decided_despite_unknowns=False).fully\n\ntests/test_track_b_insured_status.py:767: AssertionError\n______________________ test_fully_six_qcs_minimum[6-True] ______________________\n\ncount = 6, expected = True\n\n @pytest.mark.parametrize(\"count,expected\", [(5, False), (6, True)])\n def test_fully_six_qcs_minimum(count, expected):\n person = i.Person(date(2000, 2, 2))\n result = compute(\n person,\n date(2026, 12, 1),\n {2025: 4, 2026: count - 4},\n test=i.InsuredTest.FULLY,\n )\n> assert result.fully.required == 6\nE AssertionError: assert 5 == 6\nE + where 5 = StatusDecision(insured=True, qc_count_lower=6, qc_count_upper=6, required=5, window=(8000, 8001, 8002, 8003, 8004, 800... 8102, 8103, 8104, 8105, 8106, 8107), upper_assigned_quarters=(8100, 8101, 8102, 8103, 8104, 8105), upper_rule='fully').required\nE + where StatusDecision(insured=True, qc_count_lower=6, qc_count_upper=6, required=5, window=(8000, 8001, 8002, 8003, 8004, 800... 8102, 8103, 8104, 8105, 8106, 8107), upper_assigned_quarters=(8100, 8101, 8102, 8103, 8104, 8105), upper_rule='fully') = InsuredStatus(version='track-b-insured-v1', month=datetime.date(2026, 12, 1), fully=StatusDecision(insured=True, qc_co...8102, 8103), 2026: (8104, 8105)}), unknown_years=(), convention_years=mappingproxy({}), decided_despite_unknowns=False).fully\n\ntests/test_track_b_insured_status.py:767: AssertionError\n=========================== short test summary info ============================\nFAILED tests/test_track_b_insured_status.py::test_fully_six_qcs_minimum[5-False]\nFAILED tests/test_track_b_insured_status.py::test_fully_six_qcs_minimum[6-True]\n2 failed, 46 deselected in 23.71s\n", + "restored": true + }, + { + "name": "currently_requirement_6_to_5", + "before": "_window(end, 13, periods, boundary),\n 6,", + "after": "_window(end, 13, periods, boundary),\n 5,", + "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status.py -k test_currently_six_qcs_boundary", + "exit_code": 1, + "seconds": 46.04, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status.py::test_currently_six_qcs_boundary[5-False]", + "FAILED tests/test_track_b_insured_status.py::test_currently_six_qcs_boundary[6-True]" + ], + "output": "FF [100%]\n=================================== FAILURES ===================================\n___________________ test_currently_six_qcs_boundary[5-False] ___________________\n\ncount = 5, expected = False\n\n @pytest.mark.parametrize(\"count,expected\", [(5, False), (6, True)])\n def test_currently_six_qcs_boundary(count, expected):\n person = i.Person(date(1990, 2, 2))\n result = compute(\n person,\n date(2026, 12, 1),\n {2025: 4, 2026: count - 4},\n test=i.InsuredTest.CURRENTLY,\n )\n> assert result.currently.required == 6\nE AssertionError: assert 5 == 6\nE + where 5 = StatusDecision(insured=True, qc_count_lower=5, qc_count_upper=5, required=5, window=(8095, 8096, 8097, 8098, 8099, 810... 8103, 8104, 8105, 8106, 8107), upper_assigned_quarters=(8100, 8101, 8102, 8103, 8104), upper_rule='currently_6_of_13').required\nE + where StatusDecision(insured=True, qc_count_lower=5, qc_count_upper=5, required=5, window=(8095, 8096, 8097, 8098, 8099, 810... 8103, 8104, 8105, 8106, 8107), upper_assigned_quarters=(8100, 8101, 8102, 8103, 8104), upper_rule='currently_6_of_13') = InsuredStatus(version='track-b-insured-v1', month=datetime.date(2026, 12, 1), fully=None, currently=StatusDecision(ins...101, 8102, 8103), 2026: (8104,)}), unknown_years=(), convention_years=mappingproxy({}), decided_despite_unknowns=False).currently\n\ntests/test_track_b_insured_status.py:744: AssertionError\n___________________ test_currently_six_qcs_boundary[6-True] ____________________\n\ncount = 6, expected = True\n\n @pytest.mark.parametrize(\"count,expected\", [(5, False), (6, True)])\n def test_currently_six_qcs_boundary(count, expected):\n person = i.Person(date(1990, 2, 2))\n result = compute(\n person,\n date(2026, 12, 1),\n {2025: 4, 2026: count - 4},\n test=i.InsuredTest.CURRENTLY,\n )\n> assert result.currently.required == 6\nE AssertionError: assert 5 == 6\nE + where 5 = StatusDecision(insured=True, qc_count_lower=6, qc_count_upper=6, required=5, window=(8095, 8096, 8097, 8098, 8099, 810... 8104, 8105, 8106, 8107), upper_assigned_quarters=(8100, 8101, 8102, 8103, 8104, 8105), upper_rule='currently_6_of_13').required\nE + where StatusDecision(insured=True, qc_count_lower=6, qc_count_upper=6, required=5, window=(8095, 8096, 8097, 8098, 8099, 810... 8104, 8105, 8106, 8107), upper_assigned_quarters=(8100, 8101, 8102, 8103, 8104, 8105), upper_rule='currently_6_of_13') = InsuredStatus(version='track-b-insured-v1', month=datetime.date(2026, 12, 1), fully=None, currently=StatusDecision(ins...8102, 8103), 2026: (8104, 8105)}), unknown_years=(), convention_years=mappingproxy({}), decided_despite_unknowns=False).currently\n\ntests/test_track_b_insured_status.py:744: AssertionError\n=========================== short test summary info ============================\nFAILED tests/test_track_b_insured_status.py::test_currently_six_qcs_boundary[5-False]\nFAILED tests/test_track_b_insured_status.py::test_currently_six_qcs_boundary[6-True]\n2 failed, 46 deselected in 17.67s\n", + "restored": true + }, + { + "name": "regular_disability_20_to_19", + "before": "_window(end, 40, periods, boundary),\n 20,", + "after": "_window(end, 40, periods, boundary),\n 19,", + "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status.py -k test_disability_twenty_qcs_boundary", + "exit_code": 1, + "seconds": 75.26, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status.py::test_disability_twenty_qcs_boundary[19-False]", + "FAILED tests/test_track_b_insured_status.py::test_disability_twenty_qcs_boundary[20-True]" + ], + "output": "FF [100%]\n=================================== FAILURES ===================================\n________________ test_disability_twenty_qcs_boundary[19-False] _________________\n\ncount = 19, expected = False\n\n @pytest.mark.parametrize(\"count,expected\", [(19, False), (20, True)])\n def test_disability_twenty_qcs_boundary(count, expected):\n person = i.Person(date(1990, 2, 2))\n counts = {2021: 4, 2022: 4, 2023: 4, 2024: 4, 2025: count - 16}\n result = compute(person, date(2026, 12, 1), counts)\n assert result.fully.insured\n> assert result.disability.required == 20\nE AssertionError: assert 19 == 20\nE + where 19 = StatusDecision(insured=True, qc_count_lower=19, qc_count_upper=19, required=19, window=(8068, 8069, 8070, 8071, 8072, ... 8089, 8090, 8091, 8092, 8093, 8094, 8095, 8096, 8097, 8098, 8099, 8100, 8101, 8102), upper_rule='disability_20_of_40').required\nE + where StatusDecision(insured=True, qc_count_lower=19, qc_count_upper=19, required=19, window=(8068, 8069, 8070, 8071, 8072, ... 8089, 8090, 8091, 8092, 8093, 8094, 8095, 8096, 8097, 8098, 8099, 8100, 8101, 8102), upper_rule='disability_20_of_40') = InsuredStatus(version='track-b-insured-v1', month=datetime.date(2026, 12, 1), fully=StatusDecision(insured=True, qc_co...5: (8100, 8101, 8102), 2026: ()}), unknown_years=(), convention_years=mappingproxy({}), decided_despite_unknowns=False).disability\n\ntests/test_track_b_insured_status.py:754: AssertionError\n_________________ test_disability_twenty_qcs_boundary[20-True] _________________\n\ncount = 20, expected = True\n\n @pytest.mark.parametrize(\"count,expected\", [(19, False), (20, True)])\n def test_disability_twenty_qcs_boundary(count, expected):\n person = i.Person(date(1990, 2, 2))\n counts = {2021: 4, 2022: 4, 2023: 4, 2024: 4, 2025: count - 16}\n result = compute(person, date(2026, 12, 1), counts)\n assert result.fully.insured\n> assert result.disability.required == 20\nE AssertionError: assert 19 == 20\nE + where 19 = StatusDecision(insured=True, qc_count_lower=20, qc_count_upper=20, required=19, window=(8068, 8069, 8070, 8071, 8072, ... 8090, 8091, 8092, 8093, 8094, 8095, 8096, 8097, 8098, 8099, 8100, 8101, 8102, 8103), upper_rule='disability_20_of_40').required\nE + where StatusDecision(insured=True, qc_count_lower=20, qc_count_upper=20, required=19, window=(8068, 8069, 8070, 8071, 8072, ... 8090, 8091, 8092, 8093, 8094, 8095, 8096, 8097, 8098, 8099, 8100, 8101, 8102, 8103), upper_rule='disability_20_of_40') = InsuredStatus(version='track-b-insured-v1', month=datetime.date(2026, 12, 1), fully=StatusDecision(insured=True, qc_co...00, 8101, 8102, 8103), 2026: ()}), unknown_years=(), convention_years=mappingproxy({}), decided_despite_unknowns=False).disability\n\ntests/test_track_b_insured_status.py:754: AssertionError\n=========================== short test summary info ============================\nFAILED tests/test_track_b_insured_status.py::test_disability_twenty_qcs_boundary[19-False]\nFAILED tests/test_track_b_insured_status.py::test_disability_twenty_qcs_boundary[20-True]\n2 failed, 46 deselected in 44.47s\n", + "restored": true + }, + { + "name": "young_half_quarters_to_one_third", + "before": "max(6, len(elapsed) // 2)", + "after": "max(6, len(elapsed) // 3)", + "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status.py -k test_fred_brown_35_quarters_require_17_poms_140_example_1", + "exit_code": 1, + "seconds": 38.1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status.py::test_fred_brown_35_quarters_require_17_poms_140_example_1" + ], + "output": "F [100%]\n=================================== FAILURES ===================================\n__________ test_fred_brown_35_quarters_require_17_poms_140_example_1 ___________\n\n def test_fred_brown_35_quarters_require_17_poms_140_example_1():\n person = i.Person(date(1958, 5, 13), disability_onset=date(1988, 1, 15))\n result = compute(\n person,\n date(1988, 1, 1),\n {1980: 4, 1981: 4, 1982: 4, 1983: 4, 1984: 1},\n )\n> assert result.disability.required == 17\nE AssertionError: assert 11 == 17\nE + where 11 = StatusDecision(insured=True, qc_count_lower=17, qc_count_upper=17, required=11, window=(7918, 7919, 7920, 7921, 7922, ...922, 7923, 7924, 7925, 7926, 7927, 7928, 7929, 7930, 7931, 7932, 7933, 7934, 7935, 7936), upper_rule='under31_special').required\nE + where StatusDecision(insured=True, qc_count_lower=17, qc_count_upper=17, required=11, window=(7918, 7919, 7920, 7921, 7922, ...922, 7923, 7924, 7925, 7926, 7927, 7928, 7929, 7930, 7931, 7932, 7933, 7934, 7935, 7936), upper_rule='under31_special') = InsuredStatus(version='track-b-insured-v1', month=datetime.date(1988, 1, 1), fully=StatusDecision(insured=True, qc_cou...), 1986: (), 1987: (), 1988: ()}), unknown_years=(), convention_years=mappingproxy({}), decided_despite_unknowns=False).disability\n\ntests/test_track_b_insured_status.py:91: AssertionError\n=========================== short test summary info ============================\nFAILED tests/test_track_b_insured_status.py::test_fred_brown_35_quarters_require_17_poms_140_example_1\n1 failed, 47 deselected in 22.15s\n", + "restored": true + } + ], + "sha256_after": "b6bf989787bd465e080a435d77a178cee9ef861535eac190ab7fca9bd1033fc8", + "restored": true, + "verification": [ + { + "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status.py -x", + "result": "Initial suite:30passed234.26s; after DLI/world optimization and subsequent examples:42passed32.10s." + }, + { + "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status.py", + "result": "46passed34.70s before finaltwo registry tests; initial48-case run47passed1failed (FRAcompletionhad39ratherthan40QCs beforeFRAquarter; fixedinventedcompletionadds2009)." + }, + { + "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status.py -k \"dli_fra_cap or age_attainment\"", + "result": "2passed46deselected29.92s aftercorrectedcompletion." + }, + { + "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/estimates/test_birth_evidence_artifact.py -k \"not test_artifact_rebuild_reproduces\"", + "result": "13passed92.91s." + }, + { + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m black -l 79 --check tests/test_track_b_insured_status.py scripts/first_estimates_birth_evidence.py tests/estimates/test_birth_evidence_artifact.py", + "result": "3files would be left unchanged." + }, + { + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m ruff check tests/test_track_b_insured_status.py scripts/first_estimates_birth_evidence.py tests/estimates/test_birth_evidence_artifact.py", + "result": "Allchecks passed." + }, + { + "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_gross_benefits_fix_round_15_collections.py tests/test_track_b_gross_benefits_fix_round_15_arguments.py", + "result": "575 passed,36 failed in96.03s; all failures were missing insured_status COMPUTE/EVALUATE fixture map entries, fixed locally in arguments test." + }, + { + "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_gross_benefits_fix_round_15_arguments.py -k \"insured_status or CoverageYear or DisabilityPeriod or Person\"", + "result": "36 passed,272 deselected in11.03s." + }, + { + "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_gross_benefits_fix_round_15_collections.py tests/test_track_b_gross_benefits_fix_round_15_arguments.py", + "result": "611 passed in52.69s." + }, + { + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m black -l79 tests/test_track_b_gross_benefits_fix_round_15_arguments.py", + "result": "1 file unchanged." + }, + { + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m ruff check tests/test_track_b_gross_benefits_fix_round_15_arguments.py", + "result": "All checks passed." + } + ] + }, + "round_2_overlay_baseline": { + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_medical_onset_alone_never_freezes_fully_insured_elapsed_years tests/test_track_b_insured_status_fix_round_2.py::test_continuous_disability_can_first_qualify_after_medical_onset tests/test_track_b_insured_status_fix_round_2.py::test_currently_insured_excludes_period_containing_dib_event tests/test_track_b_insured_status_fix_round_2.py::test_unknown_prerequisite_count_bounds_contain_witness_switch_fillings tests/test_track_b_insured_status_fix_round_2.py::test_never_assigned_ssn_retains_sspa211_additional_requirement tests/test_track_b_insured_status_fix_round_2.py::test_established_current_period_starts_only_when_disabled_and_insured tests/test_track_b_insured_status_fix_round_2.py::test_unknown_period_status_and_dli_bounds_contain_concrete_fillings tests/test_track_b_insured_status_fix_round_2.py::test_unknown_sspa_applicability_refuses_when_qcs_would_insure tests/test_track_b_insured_status_fix_round_2.py::test_missing_current_period_declaration_is_input_error_with_onset tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_contract.py::test_raw_earnings_refusals_are_own_layer", + "returncode": 0, + "summary": "20 passed in 23.90s", + "import_command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -c 'from pathlib import Path; from populace_dynamics.track_b import insured_status as i; actual = Path(i.__file__).resolve(); expected = Path('\"'\"'/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py'\"'\"'); print(actual); assert actual == expected'", + "import_result": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "ab89110bdb23a5518d87f8927d1a807c4704665da02ca577d4228f0e9d3ee203", + "original_source_unchanged": true + }, + "round_2_mutations": [ + { + "name": "medical_onset_freezes_fully_elapsed_years", + "before": " end = min(at.year, _attain(person.birth_date, 62).year)", + "after": " end = min(at.year, _attain(person.birth_date, 62).year, person.disability_onset.year if person.disability_onset else at.year)", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_medical_onset_alone_never_freezes_fully_insured_elapsed_years", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_medical_onset_alone_never_freezes_fully_insured_elapsed_years" + ], + "summary": [ + "1 failed in 50.50s" + ], + "log": "scratch/review/mutation-r2-medical_onset_freezes_fully_elapsed_years.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "ab89110bdb23a5518d87f8927d1a807c4704665da02ca577d4228f0e9d3ee203", + "restored": true + }, + { + "name": "disability_scan_stops_at_onset_quarter", + "before": " for q in range(_qid(person.disability_onset), _qid(month) + 1)", + "after": " for q in range(_qid(person.disability_onset), _qid(person.disability_onset) + 1)", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_continuous_disability_can_first_qualify_after_medical_onset", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_continuous_disability_can_first_qualify_after_medical_onset" + ], + "summary": [ + "1 failed in 31.49s" + ], + "log": "scratch/review/mutation-r2-disability_scan_stops_at_onset_quarter.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "ab89110bdb23a5518d87f8927d1a807c4704665da02ca577d4228f0e9d3ee203", + "restored": true + }, + { + "name": "currently_excludes_only_completed_periods", + "before": " prior_before = None", + "after": " prior_before = at if kind is InsuredTest.CURRENTLY else None", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_currently_insured_excludes_period_containing_dib_event", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_currently_insured_excludes_period_containing_dib_event" + ], + "summary": [ + "1 failed in 39.42s" + ], + "log": "scratch/review/mutation-r2-currently_excludes_only_completed_periods.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "ab89110bdb23a5518d87f8927d1a807c4704665da02ca577d4228f0e9d3ee203", + "restored": true + }, + { + "name": "unknown_prerequisite_uses_selected_endpoint_counts", + "before": " full_lo, full_hi = (\n (0, maximum_qcs)", + "after": " full_lo, full_hi = (\n (lo[7], hi[7])", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_unknown_prerequisite_count_bounds_contain_witness_switch_fillings", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_unknown_prerequisite_count_bounds_contain_witness_switch_fillings" + ], + "summary": [ + "1 failed in 22.13s" + ], + "log": "scratch/review/mutation-r2-unknown_prerequisite_uses_selected_endpoint_counts.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "ab89110bdb23a5518d87f8927d1a807c4704665da02ca577d4228f0e9d3ee203", + "restored": true + }, + { + "name": "never_assigned_ssn_is_treated_as_exempt", + "before": " if person.ssn_never_assigned:\n legacy = True", + "after": " if person.ssn_never_assigned:\n legacy = False", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_never_assigned_ssn_retains_sspa211_additional_requirement", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_never_assigned_ssn_retains_sspa211_additional_requirement" + ], + "summary": [ + "1 failed in 12.77s" + ], + "log": "scratch/review/mutation-r2-never_assigned_ssn_is_treated_as_exempt.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "ab89110bdb23a5518d87f8927d1a807c4704665da02ca577d4228f0e9d3ee203", + "restored": true + }, + { + "name": "established_current_period_always_starts_at_medical_onset", + "before": " if _qid(quarter) == _qid(person.disability_onset)\n else quarter", + "after": " if _qid(quarter) == _qid(person.disability_onset)\n else person.disability_onset", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_established_current_period_starts_only_when_disabled_and_insured", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_established_current_period_starts_only_when_disabled_and_insured[first-later-insured-quarter]" + ], + "summary": [ + "1 failed, 1 passed in 29.15s" + ], + "log": "scratch/review/mutation-r2-established_current_period_always_starts_at_medical_onset.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "ab89110bdb23a5518d87f8927d1a807c4704665da02ca577d4228f0e9d3ee203", + "restored": true + }, + { + "name": "unknown_period_false_lower_world_is_accepted", + "before": " and not lo[0]\n and maximum_qcs >= 6", + "after": " and not lo[0]\n and maximum_qcs >= 600", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_unknown_period_status_and_dli_bounds_contain_concrete_fillings", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_unknown_period_status_and_dli_bounds_contain_concrete_fillings" + ], + "summary": [ + "1 failed in 23.39s" + ], + "log": "scratch/review/mutation-r2-unknown_period_false_lower_world_is_accepted.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "ab89110bdb23a5518d87f8927d1a807c4704665da02ca577d4228f0e9d3ee203", + "restored": true + }, + { + "name": "unknown_sspa_applicability_is_treated_as_exempt", + "before": " return legacy\n\n\n@_declared_input", + "after": " return False if legacy is None else legacy\n\n\n@_declared_input", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_unknown_sspa_applicability_refuses_when_qcs_would_insure", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_unknown_sspa_applicability_refuses_when_qcs_would_insure" + ], + "summary": [ + "1 failed in 16.42s" + ], + "log": "scratch/review/mutation-r2-unknown_sspa_applicability_is_treated_as_exempt.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "ab89110bdb23a5518d87f8927d1a807c4704665da02ca577d4228f0e9d3ee203", + "restored": true + }, + { + "name": "missing_current_establishment_declaration_is_accepted", + "before": "def _validate_history(person, years, month, coverage_end_month, credits):\n _month(month, \"month\")\n if (\n person.disability_onset is not None\n and person.current_disability_period_provenance is None", + "after": "def _validate_history(person, years, month, coverage_end_month, credits):\n _month(month, \"month\")\n if (\n person.disability_onset is not None\n and False", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_missing_current_period_declaration_is_input_error_with_onset", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_missing_current_period_declaration_is_input_error_with_onset" + ], + "summary": [ + "1 failed in 19.01s" + ], + "log": "scratch/review/mutation-r2-missing_current_establishment_declaration_is_accepted.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "ab89110bdb23a5518d87f8927d1a807c4704665da02ca577d4228f0e9d3ee203", + "restored": true + }, + { + "name": "unknown_dli_upper_collapses_to_no_period_lower", + "before": " hi_date = _dli_cap(person, month, coverage_end_month)", + "after": " hi_date = lo_date", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_unknown_period_status_and_dli_bounds_contain_concrete_fillings", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_unknown_period_status_and_dli_bounds_contain_concrete_fillings" + ], + "summary": [ + "1 failed in 18.58s" + ], + "log": "scratch/review/mutation-r2-unknown_dli_upper_collapses_to_lower.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "3c213db1b6733d5e67566a815a93b62df58e8988dc206ae80784b494439ce3f1", + "restored": true + }, + { + "name": "unknown_current_start_metadata_causes_status_refusal", + "before": " uncertain_current_start = True", + "after": " _refuse(InsuredUnsupportedReason.UNKNOWN_PERIODS, \"Unknown prior periods may advance the current insured start\")", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_period_declarations.py::test_established_current_period_with_unknown_prior_periods_uses_bounds", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_period_declarations.py::test_established_current_period_with_unknown_prior_periods_uses_bounds" + ], + "summary": [ + "1 failed in 11.66s" + ], + "log": "scratch/review/mutation-r2-unknown_current_start_metadata_causes_status_refusal.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "3c213db1b6733d5e67566a815a93b62df58e8988dc206ae80784b494439ce3f1", + "baseline": "round_2_continuation_baseline includes all six period-declaration tests and updated applicability properties on the final source snapshot", + "restored": true + }, + { + "name": "established_current_period_ignores_six_qc_consistency_minimum", + "before": " if person.current_disability_period_established and maximum_qcs < 6:", + "after": " if person.current_disability_period_established and maximum_qcs < 0:", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_period_declarations.py::test_established_current_period_with_unknown_prior_periods_uses_bounds", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_period_declarations.py::test_established_current_period_with_unknown_prior_periods_uses_bounds" + ], + "summary": [ + "1 failed in 6.92s" + ], + "log": "scratch/review/mutation-r2-established_current_period_ignores_six_qc_consistency_minimum.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "3c213db1b6733d5e67566a815a93b62df58e8988dc206ae80784b494439ce3f1", + "baseline": "round_2_continuation_baseline includes all six period-declaration tests and updated applicability properties on the final source snapshot", + "restored": true + }, + { + "name": "coverage_refusal_precedes_provable_six_qc_input_error", + "before": " if person.current_disability_period_established and maximum_qcs < 6:", + "after": " _coverage_checks(person, years, month, totalization_credits)\n if person.current_disability_period_established and maximum_qcs < 6:", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_period_declarations.py::test_established_current_period_with_unknown_prior_periods_uses_bounds", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_period_declarations.py::test_established_current_period_with_unknown_prior_periods_uses_bounds" + ], + "summary": [ + "1 failed in 2.21s" + ], + "log": "scratch/review/mutation-r2-coverage_refusal_precedes_provable_six_qc_input_error.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "3c213db1b6733d5e67566a815a93b62df58e8988dc206ae80784b494439ce3f1", + "baseline": "round_2_continuation_baseline includes all six period-declaration tests and updated applicability properties on the final source snapshot", + "restored": true + }, + { + "name": "unknown_sspa_historical_dli_lower_is_qc_only_date", + "before": " if applicability is None:\n # A guaranteed historical fully insured witness also needs", + "after": " if False:\n # A guaranteed historical fully insured witness also needs", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_fix_round_2.py::test_unknown_sspa_applicability_does_not_block_qc_only_uninsured_result tests/test_track_b_insured_status_fix_round_2.py::test_unknown_sspa_applicability_preserves_qc_impossibility", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-final", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-final", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_unknown_sspa_applicability_does_not_block_qc_only_uninsured_result", + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_unknown_sspa_applicability_preserves_qc_impossibility" + ], + "summary": [ + "2 failed in 5.79s" + ], + "log": "scratch/review/mutation-r2-unknown_sspa_dli_lower_is_qc_only_date.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "3c213db1b6733d5e67566a815a93b62df58e8988dc206ae80784b494439ce3f1", + "baseline": "round_2_continuation_baseline includes both updated applicability tests", + "restored": true + } + ], + "round_2_overlay_extra_baselines": [ + { + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_unknown_period_status_and_dli_bounds_contain_concrete_fillings", + "returncode": 0, + "summary": "1 passed in 21.14s", + "log": "scratch/review/mutation-overlay-dli-baseline.log" + } + ], + "round_2_prior_snapshots": [ + { + "baseline": { + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_medical_onset_alone_never_freezes_fully_insured_elapsed_years tests/test_track_b_insured_status_fix_round_2.py::test_continuous_disability_can_first_qualify_after_medical_onset tests/test_track_b_insured_status_fix_round_2.py::test_currently_insured_excludes_period_containing_dib_event tests/test_track_b_insured_status_fix_round_2.py::test_unknown_prerequisite_count_bounds_contain_witness_switch_fillings tests/test_track_b_insured_status_fix_round_2.py::test_never_assigned_ssn_retains_sspa211_additional_requirement tests/test_track_b_insured_status_fix_round_2.py::test_established_current_period_starts_only_when_disabled_and_insured tests/test_track_b_insured_status_fix_round_2.py::test_unknown_period_status_and_dli_bounds_contain_concrete_fillings tests/test_track_b_insured_status_fix_round_2.py::test_unknown_sspa_applicability_refuses_when_qcs_would_insure tests/test_track_b_insured_status_fix_round_2.py::test_missing_current_period_declaration_is_input_error_with_onset", + "returncode": 0, + "summary": "10 passed in 62.52s (0:01:02)", + "import_command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -c 'from pathlib import Path; from populace_dynamics.track_b import insured_status as i; actual = Path(i.__file__).resolve(); expected = Path('\"'\"'/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py'\"'\"'); print(actual); assert actual == expected'", + "import_result": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "7e56f719aa8fd2db8fefcdf4498d91c30f0ce612506c574378f87c90619b7b66", + "original_source_unchanged": true + }, + "extra_baselines": [ + { + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_unknown_period_status_and_dli_bounds_contain_concrete_fillings", + "returncode": 0, + "summary": "1 passed in 17.61s", + "log": "scratch/review/mutation-overlay-dli-baseline.log" + } + ], + "mutations": [ + { + "name": "medical_onset_freezes_fully_elapsed_years", + "before": " end = min(at.year, _attain(person.birth_date, 62).year)", + "after": " end = min(at.year, _attain(person.birth_date, 62).year, person.disability_onset.year if person.disability_onset else at.year)", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_medical_onset_alone_never_freezes_fully_insured_elapsed_years", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_medical_onset_alone_never_freezes_fully_insured_elapsed_years" + ], + "summary": [ + "1 failed in 40.60s" + ], + "log": "scratch/review/mutation-r2-medical_onset_freezes_fully_elapsed_years.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "7e56f719aa8fd2db8fefcdf4498d91c30f0ce612506c574378f87c90619b7b66", + "restored": true + }, + { + "name": "disability_scan_stops_at_onset_quarter", + "before": " for q in range(_qid(person.disability_onset), _qid(month) + 1)", + "after": " for q in range(_qid(person.disability_onset), _qid(person.disability_onset) + 1)", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_continuous_disability_can_first_qualify_after_medical_onset", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_continuous_disability_can_first_qualify_after_medical_onset" + ], + "summary": [ + "1 failed in 79.07s (0:01:19)" + ], + "log": "scratch/review/mutation-r2-disability_scan_stops_at_onset_quarter.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "7e56f719aa8fd2db8fefcdf4498d91c30f0ce612506c574378f87c90619b7b66", + "restored": true + }, + { + "name": "currently_excludes_only_completed_periods", + "before": " prior_before = None", + "after": " prior_before = at if kind is InsuredTest.CURRENTLY else None", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_currently_insured_excludes_period_containing_dib_event", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_currently_insured_excludes_period_containing_dib_event" + ], + "summary": [ + "1 failed in 31.35s" + ], + "log": "scratch/review/mutation-r2-currently_excludes_only_completed_periods.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "7e56f719aa8fd2db8fefcdf4498d91c30f0ce612506c574378f87c90619b7b66", + "restored": true + }, + { + "name": "unknown_prerequisite_uses_selected_endpoint_counts", + "before": " full_lo, full_hi = (\n (0, maximum_qcs)", + "after": " full_lo, full_hi = (\n (lo[7], hi[7])", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_unknown_prerequisite_count_bounds_contain_witness_switch_fillings", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_unknown_prerequisite_count_bounds_contain_witness_switch_fillings" + ], + "summary": [ + "1 failed in 16.65s" + ], + "log": "scratch/review/mutation-r2-unknown_prerequisite_uses_selected_endpoint_counts.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "7e56f719aa8fd2db8fefcdf4498d91c30f0ce612506c574378f87c90619b7b66", + "restored": true + }, + { + "name": "never_assigned_ssn_is_treated_as_exempt", + "before": " if person.ssn_never_assigned:\n legacy = True", + "after": " if person.ssn_never_assigned:\n legacy = False", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_never_assigned_ssn_retains_sspa211_additional_requirement", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_never_assigned_ssn_retains_sspa211_additional_requirement" + ], + "summary": [ + "1 failed in 7.42s" + ], + "log": "scratch/review/mutation-r2-never_assigned_ssn_is_treated_as_exempt.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "7e56f719aa8fd2db8fefcdf4498d91c30f0ce612506c574378f87c90619b7b66", + "restored": true + }, + { + "name": "established_current_period_always_starts_at_medical_onset", + "before": " if _qid(quarter) == _qid(person.disability_onset)\n else quarter", + "after": " if _qid(quarter) == _qid(person.disability_onset)\n else person.disability_onset", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_established_current_period_starts_only_when_disabled_and_insured", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_established_current_period_starts_only_when_disabled_and_insured[first-later-insured-quarter]" + ], + "summary": [ + "1 failed, 1 passed in 10.79s" + ], + "log": "scratch/review/mutation-r2-established_current_period_always_starts_at_medical_onset.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "7e56f719aa8fd2db8fefcdf4498d91c30f0ce612506c574378f87c90619b7b66", + "restored": true + }, + { + "name": "unknown_period_false_lower_world_is_accepted", + "before": " and not lo[0]\n and maximum_qcs >= 6", + "after": " and not lo[0]\n and maximum_qcs >= 600", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_unknown_period_status_and_dli_bounds_contain_concrete_fillings", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_unknown_period_status_and_dli_bounds_contain_concrete_fillings" + ], + "summary": [ + "1 failed in 226.36s (0:03:46)" + ], + "log": "scratch/review/mutation-r2-unknown_period_false_lower_world_is_accepted.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "7e56f719aa8fd2db8fefcdf4498d91c30f0ce612506c574378f87c90619b7b66", + "restored": true + }, + { + "name": "unknown_sspa_applicability_is_treated_as_exempt", + "before": " return legacy\n\n\n@_declared_input", + "after": " return False if legacy is None else legacy\n\n\n@_declared_input", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_unknown_sspa_applicability_refuses_when_qcs_would_insure", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_unknown_sspa_applicability_refuses_when_qcs_would_insure" + ], + "summary": [ + "1 failed in 16.19s" + ], + "log": "scratch/review/mutation-r2-unknown_sspa_applicability_is_treated_as_exempt.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "7e56f719aa8fd2db8fefcdf4498d91c30f0ce612506c574378f87c90619b7b66", + "restored": true + }, + { + "name": "missing_current_establishment_declaration_is_accepted", + "before": "def _validate_history(person, years, month, coverage_end_month, credits):\n _month(month, \"month\")\n if (\n person.disability_onset is not None\n and person.current_disability_period_provenance is None", + "after": "def _validate_history(person, years, month, coverage_end_month, credits):\n _month(month, \"month\")\n if (\n person.disability_onset is not None\n and False", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_missing_current_period_declaration_is_input_error_with_onset", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_missing_current_period_declaration_is_input_error_with_onset" + ], + "summary": [ + "1 failed in 7.47s" + ], + "log": "scratch/review/mutation-r2-missing_current_establishment_declaration_is_accepted.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "7e56f719aa8fd2db8fefcdf4498d91c30f0ce612506c574378f87c90619b7b66", + "restored": true + }, + { + "name": "unknown_dli_upper_collapses_to_no_period_lower", + "before": " hi_date = _dli_cap(person, month, coverage_end_month)", + "after": " hi_date = lo_date", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_unknown_period_status_and_dli_bounds_contain_concrete_fillings", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_unknown_period_status_and_dli_bounds_contain_concrete_fillings" + ], + "summary": [ + "1 failed in 15.66s" + ], + "log": "scratch/review/mutation-r2-unknown_dli_upper_collapses_to_lower.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "7e56f719aa8fd2db8fefcdf4498d91c30f0ce612506c574378f87c90619b7b66", + "restored": true + } + ], + "note": "Pre-final metadata-availability compliance correction; all original source bytes unchanged during these overlay executions.", + "log_archive_directory": "scratch/review/pre-final-snapshot-7e56f719" + }, + { + "baseline": { + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_medical_onset_alone_never_freezes_fully_insured_elapsed_years tests/test_track_b_insured_status_fix_round_2.py::test_continuous_disability_can_first_qualify_after_medical_onset tests/test_track_b_insured_status_fix_round_2.py::test_currently_insured_excludes_period_containing_dib_event tests/test_track_b_insured_status_fix_round_2.py::test_unknown_prerequisite_count_bounds_contain_witness_switch_fillings tests/test_track_b_insured_status_fix_round_2.py::test_never_assigned_ssn_retains_sspa211_additional_requirement tests/test_track_b_insured_status_fix_round_2.py::test_established_current_period_starts_only_when_disabled_and_insured tests/test_track_b_insured_status_fix_round_2.py::test_unknown_period_status_and_dli_bounds_contain_concrete_fillings tests/test_track_b_insured_status_fix_round_2.py::test_unknown_sspa_applicability_refuses_when_qcs_would_insure tests/test_track_b_insured_status_fix_round_2.py::test_missing_current_period_declaration_is_input_error_with_onset tests/test_track_b_insured_status_period_declarations.py", + "returncode": 0, + "summary": "16 passed in 33.85s", + "import_command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -c 'from pathlib import Path; from populace_dynamics.track_b import insured_status as i; actual = Path(i.__file__).resolve(); expected = Path('\"'\"'/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py'\"'\"'); print(actual); assert actual == expected'", + "import_result": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "c7a153cb508eee385c82c348475cc07c0c3918c95be6ea93d534e7703422dd8a", + "original_source_unchanged": true + }, + "mutations": [ + { + "name": "medical_onset_freezes_fully_elapsed_years", + "before": " end = min(at.year, _attain(person.birth_date, 62).year)", + "after": " end = min(at.year, _attain(person.birth_date, 62).year, person.disability_onset.year if person.disability_onset else at.year)", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_medical_onset_alone_never_freezes_fully_insured_elapsed_years", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_medical_onset_alone_never_freezes_fully_insured_elapsed_years" + ], + "summary": [ + "1 failed in 10.57s" + ], + "log": "scratch/review/mutation-r2-medical_onset_freezes_fully_elapsed_years.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "c7a153cb508eee385c82c348475cc07c0c3918c95be6ea93d534e7703422dd8a", + "restored": true + }, + { + "name": "disability_scan_stops_at_onset_quarter", + "before": " for q in range(_qid(person.disability_onset), _qid(month) + 1)", + "after": " for q in range(_qid(person.disability_onset), _qid(person.disability_onset) + 1)", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_continuous_disability_can_first_qualify_after_medical_onset", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_continuous_disability_can_first_qualify_after_medical_onset" + ], + "summary": [ + "1 failed in 11.37s" + ], + "log": "scratch/review/mutation-r2-disability_scan_stops_at_onset_quarter.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "c7a153cb508eee385c82c348475cc07c0c3918c95be6ea93d534e7703422dd8a", + "restored": true + }, + { + "name": "currently_excludes_only_completed_periods", + "before": " prior_before = None", + "after": " prior_before = at if kind is InsuredTest.CURRENTLY else None", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_currently_insured_excludes_period_containing_dib_event", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_currently_insured_excludes_period_containing_dib_event" + ], + "summary": [ + "1 failed in 5.05s" + ], + "log": "scratch/review/mutation-r2-currently_excludes_only_completed_periods.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "c7a153cb508eee385c82c348475cc07c0c3918c95be6ea93d534e7703422dd8a", + "restored": true + }, + { + "name": "unknown_prerequisite_uses_selected_endpoint_counts", + "before": " full_lo, full_hi = (\n (0, maximum_qcs)", + "after": " full_lo, full_hi = (\n (lo[7], hi[7])", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_unknown_prerequisite_count_bounds_contain_witness_switch_fillings", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_unknown_prerequisite_count_bounds_contain_witness_switch_fillings" + ], + "summary": [ + "1 failed in 8.10s" + ], + "log": "scratch/review/mutation-r2-unknown_prerequisite_uses_selected_endpoint_counts.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "c7a153cb508eee385c82c348475cc07c0c3918c95be6ea93d534e7703422dd8a", + "restored": true + }, + { + "name": "never_assigned_ssn_is_treated_as_exempt", + "before": " if person.ssn_never_assigned:\n legacy = True", + "after": " if person.ssn_never_assigned:\n legacy = False", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_never_assigned_ssn_retains_sspa211_additional_requirement", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_never_assigned_ssn_retains_sspa211_additional_requirement" + ], + "summary": [ + "1 failed in 6.92s" + ], + "log": "scratch/review/mutation-r2-never_assigned_ssn_is_treated_as_exempt.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "c7a153cb508eee385c82c348475cc07c0c3918c95be6ea93d534e7703422dd8a", + "restored": true + }, + { + "name": "established_current_period_always_starts_at_medical_onset", + "before": " if _qid(quarter) == _qid(person.disability_onset)\n else quarter", + "after": " if _qid(quarter) == _qid(person.disability_onset)\n else person.disability_onset", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_established_current_period_starts_only_when_disabled_and_insured", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_established_current_period_starts_only_when_disabled_and_insured[first-later-insured-quarter]" + ], + "summary": [ + "1 failed, 1 passed in 7.82s" + ], + "log": "scratch/review/mutation-r2-established_current_period_always_starts_at_medical_onset.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "c7a153cb508eee385c82c348475cc07c0c3918c95be6ea93d534e7703422dd8a", + "restored": true + }, + { + "name": "unknown_period_false_lower_world_is_accepted", + "before": " and not lo[0]\n and maximum_qcs >= 6", + "after": " and not lo[0]\n and maximum_qcs >= 600", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_unknown_period_status_and_dli_bounds_contain_concrete_fillings", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_unknown_period_status_and_dli_bounds_contain_concrete_fillings" + ], + "summary": [ + "1 failed in 13.85s" + ], + "log": "scratch/review/mutation-r2-unknown_period_false_lower_world_is_accepted.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "c7a153cb508eee385c82c348475cc07c0c3918c95be6ea93d534e7703422dd8a", + "restored": true + }, + { + "name": "unknown_sspa_applicability_is_treated_as_exempt", + "before": " return legacy\n\n\n@_declared_input", + "after": " return False if legacy is None else legacy\n\n\n@_declared_input", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_unknown_sspa_applicability_refuses_when_qcs_would_insure", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_unknown_sspa_applicability_refuses_when_qcs_would_insure" + ], + "summary": [ + "1 failed in 22.61s" + ], + "log": "scratch/review/mutation-r2-unknown_sspa_applicability_is_treated_as_exempt.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "c7a153cb508eee385c82c348475cc07c0c3918c95be6ea93d534e7703422dd8a", + "restored": true + }, + { + "name": "missing_current_establishment_declaration_is_accepted", + "before": "def _validate_history(person, years, month, coverage_end_month, credits):\n _month(month, \"month\")\n if (\n person.disability_onset is not None\n and person.current_disability_period_provenance is None", + "after": "def _validate_history(person, years, month, coverage_end_month, credits):\n _month(month, \"month\")\n if (\n person.disability_onset is not None\n and False", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q -x tests/test_track_b_insured_status_fix_round_2.py::test_missing_current_period_declaration_is_input_error_with_onset", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-mutations", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-mutations", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_2.py::test_missing_current_period_declaration_is_input_error_with_onset" + ], + "summary": [ + "1 failed in 2.40s" + ], + "log": "scratch/review/mutation-r2-missing_current_establishment_declaration_is_accepted.log", + "source_overlay": "scratch/review/mutation-source/src/populace_dynamics/track_b/insured_status.py", + "original_source_sha256": "c7a153cb508eee385c82c348475cc07c0c3918c95be6ea93d534e7703422dd8a", + "restored": true + } + ], + "log_archive_directory": "scratch/review/pre-final-snapshot-c7a153cb", + "note": "Nine rerun mutations before the universal-minimum guard precedence correction; original source bytes unchanged during overlay executions." + } + ], + "round_2_continuation_source_sha256": "3c213db1b6733d5e67566a815a93b62df58e8988dc206ae80784b494439ce3f1", + "round_2_continuation_baseline": { + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_fix_round_2.py::test_medical_onset_alone_never_freezes_fully_insured_elapsed_years tests/test_track_b_insured_status_fix_round_2.py::test_continuous_disability_can_first_qualify_after_medical_onset tests/test_track_b_insured_status_fix_round_2.py::test_currently_insured_excludes_period_containing_dib_event tests/test_track_b_insured_status_fix_round_2.py::test_unknown_prerequisite_count_bounds_contain_witness_switch_fillings tests/test_track_b_insured_status_fix_round_2.py::test_never_assigned_ssn_retains_sspa211_additional_requirement tests/test_track_b_insured_status_fix_round_2.py::test_established_current_period_starts_only_when_disabled_and_insured tests/test_track_b_insured_status_fix_round_2.py::test_unknown_period_status_and_dli_bounds_contain_concrete_fillings tests/test_track_b_insured_status_fix_round_2.py::test_unknown_sspa_applicability_refuses_when_qcs_would_insure tests/test_track_b_insured_status_fix_round_2.py::test_missing_current_period_declaration_is_input_error_with_onset tests/test_track_b_insured_status_fix_round_2.py::test_unknown_sspa_applicability_does_not_block_qc_only_uninsured_result tests/test_track_b_insured_status_fix_round_2.py::test_unknown_sspa_applicability_preserves_qc_impossibility tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_contract.py::test_raw_earnings_refusals_are_own_layer", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r2-final", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r2-final", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-source/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/src:/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2", + "PYTHONDONTWRITEBYTECODE": "1", + "HYPOTHESIS_STORAGE_DIRECTORY": "/Users/maxghenis/.subfleet/worktrees/20261025-031318-trackb-fix-insured-2/scratch/review/mutation-hypothesis" + }, + "summary": "22 passed in 31.69s", + "returncode": 0, + "original_source_sha256": "3c213db1b6733d5e67566a815a93b62df58e8988dc206ae80784b494439ce3f1" + }, + "round_2_source_transition": { + "previous_source_sha256": "ab89110bdb23a5518d87f8927d1a807c4704665da02ca577d4228f0e9d3ee203", + "final_source_sha256": "3c213db1b6733d5e67566a815a93b62df58e8988dc206ae80784b494439ce3f1", + "completed_mutations_retained": 9, + "reason": "Only UNKNOWN SSPA211 historical DLI lower bounding changed; completed rule mutations retain their actual execution-source hashes.", + "source_diff": "--- before_unknown_sspa_dli_lower_correction\n+++ after_unknown_sspa_dli_lower_correction\n@@ -1231,6 +1231,11 @@\n hi_censored = (\n coverage_end_month is None or coverage_end_month > month\n ) and _qid(hi_date) == _qid(month)\n+ if applicability is None:\n+ # A guaranteed historical fully insured witness also needs\n+ # resolved section214(c) facts. Keep the QC-only upper date;\n+ # false current status cannot prove a positive DLI lower date.\n+ lo_date = None\n dli = _computed(DLIRange, lo_date, hi_date, lo_censored or hi_censored)\n lo_rows, _ = _world(\n lo_person,\n", + "previous_log_archive_directory": "scratch/review/pre-sspa-dli-snapshot-ab89110b" + }, + "round_2_final_original_source_sha256": "3c213db1b6733d5e67566a815a93b62df58e8988dc206ae80784b494439ce3f1" +} diff --git a/src/populace_dynamics/track_b/insured_status.py b/src/populace_dynamics/track_b/insured_status.py index 88226265b..39dd656c3 100644 --- a/src/populace_dynamics/track_b/insured_status.py +++ b/src/populace_dynamics/track_b/insured_status.py @@ -2,10 +2,14 @@ Verification class: statutory conformance. Admitted scope: declared invented histories and captured statutory examples only; no population, behavioral, -or forecast claim. Act 213, 214, 216(i), 223(c); 20 CFR 404 subpart B; +or forecast claim. Act 213, 214, 216(i), 223(c); 20 CFR 404 subpart B +and 404.315/.320/.321; POMS RS 00301. Every year is declared, including zero and unknown years. -The query month is a hypothetical entitlement/onset month, not a finding of -medical disability or administrative entitlement. Annual QC assignment is +Medical onset declares continuous disability through the query month; it +never establishes an administrative period of disability. Disability tests +scan onset and later quarters; period establishment and section 214(c) +applicability carry explicit provenance. The query month is a hypothetical +entitlement month, not medical or administrative adjudication. Annual QC assignment is favorable and retrospective; callers must supply only information available at their decision time. Each test returns its own assignment witness. @@ -19,7 +23,7 @@ import calendar from collections.abc import Callable, Mapping -from dataclasses import dataclass +from dataclasses import dataclass, replace from datetime import date, timedelta from enum import Enum from fractions import Fraction @@ -90,6 +94,11 @@ class CoverageCondition(Enum): class InsuredUnsupportedReason(Enum): UNKNOWN_EARNINGS = "unknown_earnings_years_decide_status" + UNKNOWN_PERIODS = "unknown_prior_disability_periods_decide_status" + UNKNOWN_CURRENT_PERIOD = "unknown_current_disability_period_decides_status" + UNKNOWN_SSPA211 = "sspa211_applicability_unknown" + CURRENT_PERIOD_HISTORY = "current_disability_period_requires_history" + CURRENT_PERIOD_DLI = "ongoing_disability_period_dli_horizon_unsupported" TOTALIZATION = "totalization_credits_unsupported" DEEMED_FULLY_INSURED = "deemed_fully_insured_unsupported" TRANSITIONAL_INSURED = "transitional_insured_unsupported" @@ -149,6 +158,30 @@ def _attain(birth, age): return date(year, birth.month, day) - timedelta(days=1) +def _fact_provenance(provenance, convention_id, label): + convention = provenance is EarningsProvenance.CONVENTION_FILLED + if convention != (convention_id is not None): + raise InvalidFamilyInput(f"Only convention-filled {label} needs an id") + if convention and not convention_id.strip(): + raise InvalidFamilyInput("Convention identifier must be nonempty") + + +def _sspa211_applicability(person): + # RS00301.102 B.1/B.3: pre2004 assignments are exempt; an alien + # without a true-identity SSN is subject to the additional requirement. + legacy = None + if person.alien_worker: + if person.ssn_never_assigned: + legacy = True + elif person.ssn_assignment_date is not None: + legacy = person.ssn_assignment_date >= date(2004, 1, 1) + if person.sspa211_applies is not None: + if legacy is not None and legacy != person.sspa211_applies: + raise InvalidFamilyInput("Conflicting SSPA211 applicability facts") + return person.sspa211_applies + return legacy + + @_declared_input @dataclass(frozen=True) class CoverageYear: @@ -228,8 +261,59 @@ class Person: ssn_never_assigned: bool = False rib_entitlement_month: date | None = None dib_entitlement_month: date | None = None + prior_disability_periods_provenance: EarningsProvenance = ( + EarningsProvenance.UNKNOWN + ) + prior_disability_periods_convention_id: str | None = None + current_disability_period_established: bool | None = None + current_disability_period_provenance: EarningsProvenance | None = None + current_disability_period_convention_id: str | None = None + sspa211_applies: bool | None = None + sspa211_provenance: EarningsProvenance = EarningsProvenance.UNKNOWN + sspa211_convention_id: str | None = None def __post_init__(self): + _fact_provenance( + self.prior_disability_periods_provenance, + self.prior_disability_periods_convention_id, + "prior disability periods", + ) + if ( + self.prior_disability_periods_provenance + is EarningsProvenance.UNKNOWN + and self.prior_disability_periods + ): + raise InvalidFamilyInput( + "Unknown prior periods cannot contain values" + ) + for value, provenance, convention, label in ( + ( + self.current_disability_period_established, + self.current_disability_period_provenance, + self.current_disability_period_convention_id, + "current disability period", + ), + ( + self.sspa211_applies, + self.sspa211_provenance, + self.sspa211_convention_id, + "SSPA211 applicability", + ), + ): + _fact_provenance(provenance, convention, label) + if ( + provenance is None or provenance is EarningsProvenance.UNKNOWN + ) != (value is None): + raise InvalidFamilyInput( + f"{label} value must match provenance" + ) + if ( + self.current_disability_period_established + and self.disability_onset is None + ): + raise InvalidFamilyInput( + "Current established period requires medical onset" + ) if not 1870 <= self.birth_date.year <= 9900: raise InvalidFamilyInput("Birth year outside supported calendar") if self.birth_date < date(1913, 1, 2) and self.sex is None: @@ -257,14 +341,6 @@ def __post_init__(self): raise InvalidFamilyInput( "Prior special onset must precede age31" ) - if ( - self.alien_worker - and self.ssn_assignment_date is None - and not self.ssn_never_assigned - ): - raise InvalidFamilyInput( - "Alien worker requires assignment date or explicit never-assigned fact" - ) if self.ssn_never_assigned and self.ssn_assignment_date is not None: raise InvalidFamilyInput( "Unassigned SSN cannot have assignment date" @@ -303,6 +379,8 @@ class StatusDecision(_SealedResult): upper_fully_required: int fully_qc_count_lower: int fully_qc_count_upper: int + qualifying_quarter: date | None + upper_qualifying_quarter: date | None @_sealed_result @@ -327,6 +405,9 @@ class InsuredStatus(_SealedResult): unknown_years: tuple[int, ...] convention_years: Mapping[int, str] decided_despite_unknowns: bool + current_disability_period_start: date | None + unknown_facts: tuple[str, ...] + convention_facts: Mapping[str, str] def _requirement(person, at, periods=(), *, onset=True, for_disability=False): @@ -343,12 +424,6 @@ def _requirement(person, at, periods=(), *, onset=True, for_disability=False): ) if person.death_date is not None: end = min(end, person.death_date.year) - if ( - onset - and person.disability_onset is not None - and not person.statutory_blindness - ): - end = min(end, person.disability_onset.year) elapsed = sum( not any(a.year <= year <= b.year for a, b in periods) for year in range(start, end) @@ -360,6 +435,13 @@ def _requirement(person, at, periods=(), *, onset=True, for_disability=False): def fully_insured_requirement(person: Person, month: date) -> int: """One QC per elapsed year, bounded by six and forty (214(a)).""" _month(month, "month") + if ( + person.disability_onset is not None + and person.current_disability_period_provenance is None + ): + raise InvalidFamilyInput( + "Declare current disability period establishment" + ) if month < person.birth_date.replace(day=1): raise InvalidFamilyInput("Query precedes birth") if ( @@ -369,6 +451,22 @@ def fully_insured_requirement(person: Person, month: date) -> int: raise InvalidFamilyInput("Disability onset follows query month") if any(p.end >= month for p in person.prior_disability_periods): raise InvalidFamilyInput("Prior disability period follows query month") + if ( + person.prior_disability_periods_provenance + is EarningsProvenance.UNKNOWN + ): + _refuse( + InsuredUnsupportedReason.UNKNOWN_PERIODS, + "Requirement depends on established periods", + ) + if ( + person.disability_onset is not None + and person.current_disability_period_established is not False + ): + _refuse( + InsuredUnsupportedReason.CURRENT_PERIOD_HISTORY, + "Deriving the current period start requires coverage history", + ) periods = tuple((p.start, p.end) for p in person.prior_disability_periods) return _requirement(person, month, periods) @@ -385,6 +483,14 @@ def qc_amount_from_nawi(nawi: Fraction, prior_amount: int) -> int: def _validate_history(person, years, month, coverage_end_month, credits): _month(month, "month") + if ( + person.disability_onset is not None + and person.current_disability_period_provenance is None + ): + raise InvalidFamilyInput( + "Declare current disability period establishment" + ) + _sspa211_applicability(person) if month.year > 9990 or month < person.birth_date.replace(day=1): raise InvalidFamilyInput("Query outside person's calendar") if ( @@ -480,14 +586,6 @@ def _coverage_checks(person, years, month, credits): ) for condition in sorted(person.conditions, key=lambda c: c.value): _refuse(InsuredUnsupportedReason[condition.name], condition.value) - if person.alien_worker and ( - person.ssn_never_assigned - or person.ssn_assignment_date >= date(2004, 1, 1) - ): - _refuse( - InsuredUnsupportedReason.ALIEN_WORKER, - "SSPA211 additional alien-worker facts", - ) if month < date(1968, 1, 1): _refuse( InsuredUnsupportedReason.HISTORICAL_ENTITLEMENT, @@ -530,6 +628,11 @@ def _credits(year, row, upper): 0, ) if year >= 1978: + if year > 2027: + _refuse( + InsuredUnsupportedReason.QC_YEAR, + f"No captured QC increment for {year}", + ) return (), _post1977_qc_count( year, row.wages or Fraction(0), row.self_employment or Fraction(0) ) @@ -626,7 +729,7 @@ def _witness(person, credits, at, exit_month, kind, *, onset=True): for use_periods in ( (True, False) if person.prior_disability_periods else (True,) ): - prior_before = at if kind is InsuredTest.CURRENTLY else None + prior_before = None rows, periods = _world( person, credits, @@ -805,6 +908,85 @@ def _last_insured(person, credits, month, exit_month): return last, censored +def _events(person, month, kind): + if kind is InsuredTest.DISABILITY and person.disability_onset is not None: + # 404.131(a): onset quarter OR a later quarter while disabled. + return tuple( + _qdate(q) + for q in range(_qid(person.disability_onset), _qid(month) + 1) + ) + if kind is InsuredTest.CURRENTLY: + return tuple( + event + for event in ( + person.death_date, + person.rib_entitlement_month, + person.dib_entitlement_month, + ) + if event is not None and event.replace(day=1) <= month + ) or (month,) + return (month,) + + +def _decision_witness(person, credits, month, exit_month, kind): + best, qualifying = None, None + for event in _events(person, month, kind): + witness = _witness(person, credits, event, exit_month, kind) + if witness[0] and kind is InsuredTest.DISABILITY: + return witness, _qdate(_qid(event)) + if best is None or (witness[0], witness[1]) > (best[0], best[1]): + best = witness + qualifying = _qdate(_qid(event)) if witness[0] else None + return best, qualifying + + +def _with_current_period(person, credits, month, exit_month): + if not person.current_disability_period_established: + return person, None + witness, quarter = _decision_witness( + person, credits, month, exit_month, InsuredTest.DISABILITY + ) + if not witness[0]: + raise InvalidFamilyInput( + "Established current period has no insured disabled quarter" + ) + # 416(i)(2)(C), 404.321(a): onset day if insured then, otherwise + # first day of the first later insured quarter. Application/duration + # are administrative facts declared by the caller, never inferred. + start = ( + person.disability_onset + if _qid(quarter) == _qid(person.disability_onset) + else quarter + ) + end = date( + month.year, + month.month, + calendar.monthrange(month.year, month.month)[1], + ) + if person.death_date is not None: + end = min(end, person.death_date) + period = DisabilityPeriod(start, end) + return ( + replace( + person, + prior_disability_periods=person.prior_disability_periods + + (period,), + prior_disability_periods_provenance=EarningsProvenance.OBSERVED, + prior_disability_periods_convention_id=None, + ), + start, + ) + + +def _dli_cap(person, month, exit_month): + cap = min(_qid(month), _fra_quarter(person) - 1) + if exit_month is not None and exit_month <= month: + cap = _fra_quarter(person) - 1 + if person.death_date is not None: + cap = min(cap, _qid(person.death_date)) + return _qend(cap) + + @_validated_entry def insured_status( person: Person, @@ -815,16 +997,18 @@ def insured_status( coverage_end_month: date | None = None, totalization_credits: tuple[str, ...] = (), ) -> InsuredStatus: - """Decide a declared person-month; uncertain status is a retained refusal. - - B6a calls with test=FULLY. OP8(d)/OP12 use the same declaration and - optional exit month. No entry date, imputation, or zero default exists. - DLI is through this query, explicitly censored, unless exit freezes work. + """Decide declared insurance, retaining coverage refusals in denominators. + + Medical onset means continuously disabled through this query and never + establishes a period. Declare establishment, prior-period provenance, + and section214(c) applicability; UNKNOWN never silently means none. + Each disability window ends at its tested quarter, from onset through + query, and the first insured quarter supplies the witness (404.131). + No entry date, imputation, or pre-entry zero convention exists. """ _validate_history( person, years, month, coverage_end_month, totalization_credits ) - _coverage_checks(person, years, month, totalization_credits) lower = {y: _credits(y, row, False) for y, row in sorted(years.items())} upper = {y: _credits(y, row, True) for y, row in sorted(years.items())} unknown = tuple( @@ -832,6 +1016,105 @@ def insured_status( for y, row in sorted(years.items()) if row.provenance is EarningsProvenance.UNKNOWN ) + prior_unknown = ( + person.prior_disability_periods_provenance + is EarningsProvenance.UNKNOWN + ) + current_unknown = ( + person.disability_onset is not None + and person.current_disability_period_provenance + is EarningsProvenance.UNKNOWN + ) + max_rows, _ = _world( + person, + upper, + _qid(month), + coverage_end_month, + False, + include_zero=True, + ) + maximum_qcs = sum(len(_assign_qcs(*row)) for row in max_rows.values()) + if person.current_disability_period_established and maximum_qcs < 6: + raise InvalidFamilyInput( + "Established current period requires at least six lifetime QCs" + ) + _coverage_checks(person, years, month, totalization_credits) + applicability = _sspa211_applicability(person) + # Known applicable cases require unimplemented work-authorization/visa + # adjudication. Unknown applicability can decide a QC-only false result. + if applicability is True: + _refuse( + InsuredUnsupportedReason.ALIEN_WORKER, + "SSPA211 additional alien-worker facts", + ) + # Favorable disregard is a treatment, not a claim that a known + # established period never existed (404.320(a),404.130(f)). Unknown + # prior periods cannot be mixed selectively with the current period. + uncertain_current_start = False + if prior_unknown: + lo_person = hi_person = person + lo_start = hi_start = None + if person.current_disability_period_established: + onset_witness = _witness( + person, + lower, + person.disability_onset, + coverage_end_month, + InsuredTest.DISABILITY, + ) + if onset_witness[0]: + lo_start = hi_start = person.disability_onset + else: + uncertain_current_start = True + else: + if person.current_disability_period_established: + initial_lo, _ = _decision_witness( + person, + lower, + month, + coverage_end_month, + InsuredTest.DISABILITY, + ) + if not initial_lo[0] and unknown: + initial_hi, _ = _decision_witness( + person, + upper, + month, + coverage_end_month, + InsuredTest.DISABILITY, + ) + if initial_hi[0]: + _refuse( + InsuredUnsupportedReason.UNKNOWN_EARNINGS, + "Unknown facts decide the established current insured start", + ) + lo_person, lo_start = _with_current_period( + person, lower, month, coverage_end_month + ) + hi_person, hi_start = ( + _with_current_period(person, upper, month, coverage_end_month) + if unknown + else (lo_person, lo_start) + ) + if lo_start != hi_start: + _refuse( + InsuredUnsupportedReason.UNKNOWN_EARNINGS, + "Unknown earnings decide established current period start", + ) + # The current disability is known only through the query. A frozen-exit + # future DLI would require its unobserved recovery/end date. + if ( + person.current_disability_period_established + and not prior_unknown + and coverage_end_month is not None + and coverage_end_month <= month + and _dli_cap(person, month, coverage_end_month) > _qend(_qid(month)) + and test in (InsuredTest.ALL, InsuredTest.DISABILITY) + ): + _refuse( + InsuredUnsupportedReason.CURRENT_PERIOD_DLI, + "Current period end beyond query is unobserved", + ) decisions = {} for kind in ( InsuredTest.FULLY, @@ -841,52 +1124,83 @@ def insured_status( decisions[kind] = None if test not in (InsuredTest.ALL, kind): continue - at = month - if ( - kind is InsuredTest.DISABILITY - and person.disability_onset is not None - and not person.statutory_blindness - ): - at = person.disability_onset - events = [at] - if kind is InsuredTest.CURRENTLY: - events = [ - event - for event in ( - person.death_date, - person.rib_entitlement_month, - person.dib_entitlement_month, - ) - if event is not None and event.replace(day=1) <= month - ] or [month] - lo = max( - ( - _witness(person, lower, event, coverage_end_month, kind) - for event in events - ), - key=lambda witness: (witness[0], witness[1]), + # Establishment follows the first insured quarter; using its own + # exclusion to prove that quarter would be circular. Subsequent + # hypothetical-onset DLI quarters can use the established period. + decision_lo_person = ( + person if kind is InsuredTest.DISABILITY else lo_person ) - hi = ( - max( - ( - _witness(person, upper, event, coverage_end_month, kind) - for event in events - ), - key=lambda witness: (witness[0], witness[1]), + decision_hi_person = ( + person if kind is InsuredTest.DISABILITY else hi_person + ) + lo, lo_quarter = _decision_witness( + decision_lo_person, lower, month, coverage_end_month, kind + ) + hi, hi_quarter = ( + _decision_witness( + decision_hi_person, upper, month, coverage_end_month, kind ) if unknown - else lo + else (lo, lo_quarter) ) if lo[0] != hi[0]: _refuse( InsuredUnsupportedReason.UNKNOWN_EARNINGS, f"{kind.value} differs across unknown years {unknown}", ) + # Six lifetime QCs is a universal prerequisite. Otherwise an + # unknown period could supply exclusions or earlier special status. + if ( + ( + prior_unknown + or current_unknown + and kind is not InsuredTest.DISABILITY + ) + and not lo[0] + and maximum_qcs >= 6 + ): + _refuse( + ( + InsuredUnsupportedReason.UNKNOWN_PERIODS + if prior_unknown + else InsuredUnsupportedReason.UNKNOWN_CURRENT_PERIOD + ), + f"Unknown established periods may change {kind.value}", + ) + if applicability is None and lo[0]: + _refuse( + InsuredUnsupportedReason.UNKNOWN_SSPA211, + f"SSPA211 applicability may change {kind.value}", + ) + # A selected witness can switch as credits rise; its count is not + # monotone. With uncertain credits and treatment/witness choices, + # use the universal envelope: every assignment has 0..maximum_qcs. + broad = ( + prior_unknown + or current_unknown + or bool(unknown) + and ( + bool(person.prior_disability_periods) + or person.disability_onset is not None + or kind is InsuredTest.CURRENTLY + and len(_events(person, month, kind)) > 1 + ) + ) + count_lo, count_hi = ( + (0, maximum_qcs) + if broad + else (min(lo[1], hi[1]), max(lo[1], hi[1])) + ) + full_lo, full_hi = ( + (0, maximum_qcs) + if broad + else (min(lo[7], hi[7]), max(lo[7], hi[7])) + ) decisions[kind] = _computed( StatusDecision, lo[0], - lo[1], - hi[1], + count_lo, + count_hi, lo[2], lo[3], lo[4], @@ -897,27 +1211,74 @@ def insured_status( hi[5], lo[6], hi[6], - lo[7], - hi[7], + full_lo, + full_hi, + lo_quarter, + hi_quarter, ) dli = None if test in (InsuredTest.ALL, InsuredTest.DISABILITY): lo_date, lo_censored = _last_insured( - person, lower, month, coverage_end_month + lo_person, lower, month, coverage_end_month ) hi_date, hi_censored = ( - _last_insured(person, upper, month, coverage_end_month) + _last_insured(hi_person, upper, month, coverage_end_month) if unknown else (lo_date, lo_censored) ) + if (prior_unknown or current_unknown) and maximum_qcs >= 6: + hi_date = _dli_cap(person, month, coverage_end_month) + hi_censored = ( + coverage_end_month is None or coverage_end_month > month + ) and _qid(hi_date) == _qid(month) + if applicability is None: + # A guaranteed historical fully insured witness also needs + # resolved section214(c) facts. Keep the QC-only upper date; + # false current status cannot prove a positive DLI lower date. + lo_date = None dli = _computed(DLIRange, lo_date, hi_date, lo_censored or hi_censored) lo_rows, _ = _world( - person, lower, _qid(month), coverage_end_month, True, include_zero=True + lo_person, + lower, + _qid(month), + coverage_end_month, + True, + include_zero=True, ) hi_rows, _ = _world( - person, upper, _qid(month), coverage_end_month, True, include_zero=True + hi_person, + upper, + _qid(month), + coverage_end_month, + True, + include_zero=True, ) assigned = {y: _assign_qcs(*row) for y, row in lo_rows.items()} + unknown_facts = tuple( + name + for name, missing in ( + ("prior_disability_periods", prior_unknown), + ("current_disability_period", current_unknown), + ("current_disability_period_start", uncertain_current_start), + ("sspa211_applicability", applicability is None), + ) + if missing + ) + conventions = { + name: identifier + for name, identifier in ( + ( + "prior_disability_periods", + person.prior_disability_periods_convention_id, + ), + ( + "current_disability_period", + person.current_disability_period_convention_id, + ), + ("sspa211_applicability", person.sspa211_convention_id), + ) + if identifier is not None + } return _computed( InsuredStatus, VERSION, @@ -928,7 +1289,18 @@ def insured_status( dli, MappingProxyType( { - y: (len(assigned[y]), len(_assign_qcs(*hi_rows[y]))) + y: ( + ( + 0 + if prior_unknown or current_unknown + else len(assigned[y]) + ), + ( + len(_assign_qcs(*max_rows[y])) + if prior_unknown or current_unknown + else len(_assign_qcs(*hi_rows[y])) + ), + ) for y in lo_rows } ), @@ -941,7 +1313,10 @@ def insured_status( if row.provenance is EarningsProvenance.CONVENTION_FILLED } ), - bool(unknown), + bool(unknown or unknown_facts), + lo_start, + unknown_facts, + MappingProxyType(conventions), ) diff --git a/tests/data/track_b/insured_status_examples.yaml b/tests/data/track_b/insured_status_examples.yaml index 4d6461991..1c370286b 100644 --- a/tests/data/track_b/insured_status_examples.yaml +++ b/tests/data/track_b/insured_status_examples.yaml @@ -84,6 +84,34 @@ examples: required_qcs: 6 coverage: computed test_node: tests/test_track_b_insured_status.py::test_sam_white_6_in_12_poms_140_example_2 +- id: poms_140_sam_later + source: poms_rs_00301_140 + quotes: + - 8/20/61 + - 4/12/84 + - seven quarters + - 6 QC's + - 9/81 through 6/84 + - However, they may have insured status at a later date. + expected: + birth: '1961-08-20' + onset: '1984-04-12' + required_qcs: 6 + onset_insured: false + later_insured: true + invented_completion: + year_qcs: + 1983: 3 + 1984: 3 + first_insured_quarter: 1984-Q3 + coverage: computed + note: The source supplies the six-QC rule and expressly permits later insured + status, but supplies neither an earnings history nor a later insured date. + The execution test declares an invented annual-QC completion, yielding five + assignable QCs in the onset quarter and six in the next quarter. The later + date is an invented demonstration of the published rule, not a published + numerical result. + test_node: tests/test_track_b_insured_status_fix_round_2.py::test_sam_white_can_become_insured_later_poms_140_example_2 - id: poms_140_mary_met source: poms_rs_00301_140 quotes: diff --git a/tests/data/track_b/insured_status_mutation_checks.json b/tests/data/track_b/insured_status_mutation_checks.json deleted file mode 100644 index b9f0b2e67..000000000 --- a/tests/data/track_b/insured_status_mutation_checks.json +++ /dev/null @@ -1,418 +0,0 @@ -{ - "verification_class": "statutory_conformance", - "scope": "Invented and captured statutory cases only; no population, behavioral or forecast claim.", - "qc_mutations": [ - { - "name": "qc_cap_4_to_3", - "before": "return min(4, (wages + self_employment) // QC_AMOUNTS[year])", - "after": "return min(3, (wages + self_employment) // QC_AMOUNTS[year])", - "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary", - "returncode": 1, - "failed_tests": [ - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1978]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1979]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1980]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1981]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1982]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1983]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1984]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1985]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1986]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1987]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1988]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1989]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1990]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1991]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1992]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1993]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1994]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1995]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1996]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1997]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1998]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-1999]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2000]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2001]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2002]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2003]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2004]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2005]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2006]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2007]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2008]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2009]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2010]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2011]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2012]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2013]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2014]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2015]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2016]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2017]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2018]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2019]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2020]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2021]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2022]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2023]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2024]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2025]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2026]", - "FAILED tests/test_track_b_insured_status_qc.py::test_published_increment_exact_boundary[4-2027]" - ], - "summary": [ - "50 failed, 150 passed in 15.27s" - ], - "environment": { - "OMP_NUM_THREADS": "1", - "POLARS_MAX_THREADS": "1", - "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/track-b-insured-psid", - "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/track-b-insured-epuf", - "PYTHONPATH": "$PWD/src:$PWD", - "PYTHONDONTWRITEBYTECODE": "1" - }, - "restored": true - }, - { - "name": "round_drop_half_tie", - "before": "rounded = ((indexed + 5) // 10) * 10", - "after": "rounded = ((indexed + 0) // 10) * 10", - "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_qc.py::test_qc_amount_ties_round_up", - "returncode": 1, - "failed_tests": [ - "FAILED tests/test_track_b_insured_status_qc.py::test_qc_amount_ties_round_up[delta1-260]", - "FAILED tests/test_track_b_insured_status_qc.py::test_qc_amount_ties_round_up[delta2-260]" - ], - "summary": [ - "2 failed, 1 passed in 6.57s" - ], - "environment": { - "OMP_NUM_THREADS": "1", - "POLARS_MAX_THREADS": "1", - "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/track-b-insured-psid", - "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/track-b-insured-epuf", - "PYTHONPATH": "$PWD/src:$PWD", - "PYTHONDONTWRITEBYTECODE": "1" - }, - "restored": true - }, - { - "name": "wage_50_inclusive_to_strict", - "before": "if wages >= 50", - "after": "if wages > 50", - "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary", - "returncode": 1, - "failed_tests": [ - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1937]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1938]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1939]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1940]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1941]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1942]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1943]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1944]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1945]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1946]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1947]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1948]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1949]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1950]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1951]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1952]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1953]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1954]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1955]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1956]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1957]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1958]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1959]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1960]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1961]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1962]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1963]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1964]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1965]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1966]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1967]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1968]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1969]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1970]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1971]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1972]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1973]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1974]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1975]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1976]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_fifty_dollar_quarter_boundary[1977]" - ], - "summary": [ - "41 failed in 16.30s" - ], - "environment": { - "OMP_NUM_THREADS": "1", - "POLARS_MAX_THREADS": "1", - "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/track-b-insured-psid", - "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/track-b-insured-epuf", - "PYTHONPATH": "$PWD/src:$PWD", - "PYTHONDONTWRITEBYTECODE": "1" - }, - "restored": true - }, - { - "name": "sei_400_inclusive_to_strict", - "before": "or self_employment >= 400", - "after": "or self_employment > 400", - "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary", - "returncode": 1, - "failed_tests": [ - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1951]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1952]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1953]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1954]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1955]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1956]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1957]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1958]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1959]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1960]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1961]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1962]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1963]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1964]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1965]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1966]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1967]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1968]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1969]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1970]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1971]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1972]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1973]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1974]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1975]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1976]", - "FAILED tests/test_track_b_insured_status_qc.py::test_pre1978_calendar_sei_four_hundred_boundary[1977]" - ], - "summary": [ - "27 failed in 9.66s" - ], - "environment": { - "OMP_NUM_THREADS": "1", - "POLARS_MAX_THREADS": "1", - "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/track-b-insured-psid", - "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/track-b-insured-epuf", - "PYTHONPATH": "$PWD/src:$PWD", - "PYTHONDONTWRITEBYTECODE": "1" - }, - "restored": true - }, - { - "name": "disability_exclude_first_endpoint", - "before": "start < quarter < end", - "after": "start <= quarter < end", - "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_qc.py::test_death_future_exit_and_disability_endpoint_exclusions", - "returncode": 1, - "failed_tests": [ - "FAILED tests/test_track_b_insured_status_qc.py::test_death_future_exit_and_disability_endpoint_exclusions" - ], - "summary": [ - "1 failed in 7.23s" - ], - "environment": { - "OMP_NUM_THREADS": "1", - "POLARS_MAX_THREADS": "1", - "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/track-b-insured-psid", - "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/track-b-insured-epuf", - "PYTHONPATH": "$PWD/src:$PWD", - "PYTHONDONTWRITEBYTECODE": "1" - }, - "restored": true - }, - { - "name": "assignment_maximize_to_minimize", - "before": "-len(target.intersection(candidate))", - "after": "len(target.intersection(candidate))", - "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_qc.py::test_rs00301_230_henry_and_325_john_retroactive_assignment", - "returncode": 1, - "failed_tests": [ - "FAILED tests/test_track_b_insured_status_qc.py::test_rs00301_230_henry_and_325_john_retroactive_assignment" - ], - "summary": [ - "1 failed in 6.27s" - ], - "environment": { - "OMP_NUM_THREADS": "1", - "POLARS_MAX_THREADS": "1", - "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/track-b-insured-psid", - "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/track-b-insured-epuf", - "PYTHONPATH": "$PWD/src:$PWD", - "PYTHONDONTWRITEBYTECODE": "1" - }, - "restored": true - }, - { - "name": "agricultural_increment_100_to_200", - "before": "agricultural_wages // 100", - "after": "agricultural_wages // 200", - "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_qc.py::test_rs00301_320_jane_agricultural_example", - "returncode": 1, - "failed_tests": [ - "FAILED tests/test_track_b_insured_status_qc.py::test_rs00301_320_jane_agricultural_example" - ], - "summary": [ - "1 failed in 5.11s" - ], - "environment": { - "OMP_NUM_THREADS": "1", - "POLARS_MAX_THREADS": "1", - "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/track-b-insured-psid", - "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/track-b-insured-epuf", - "PYTHONPATH": "$PWD/src:$PWD", - "PYTHONDONTWRITEBYTECODE": "1" - }, - "restored": true - }, - { - "name": "gift_maximum_inclusive_to_strict", - "before": "wages + self_employment >= _annual_wage_limit(year)", - "after": "wages + self_employment > _annual_wage_limit(year)", - "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs", - "returncode": 1, - "failed_tests": [ - "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1937-1950-3000]", - "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1951-1954-3600]", - "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1955-1958-4200]", - "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1959-1965-4800]", - "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1966-1967-6600]", - "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1968-1971-7800]", - "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1972-1972-9000]", - "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1973-1973-10800]", - "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1974-1974-13200]", - "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1975-1975-14100]", - "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1976-1976-15300]", - "FAILED tests/test_track_b_insured_status_qc.py::test_maximum_taxable_wages_give_four_gift_qcs[1977-1977-16500]" - ], - "summary": [ - "12 failed in 3.60s" - ], - "environment": { - "OMP_NUM_THREADS": "1", - "POLARS_MAX_THREADS": "1", - "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/track-b-insured-psid", - "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/track-b-insured-epuf", - "PYTHONPATH": "$PWD/src:$PWD", - "PYTHONDONTWRITEBYTECODE": "1" - }, - "restored": true - } - ], - "status_mutations": { - "file": "src/populace_dynamics/track_b/insured_status.py", - "sha256_before": "b6bf989787bd465e080a435d77a178cee9ef861535eac190ab7fca9bd1033fc8", - "mutations": [ - { - "name": "fully_minimum_6_to_5", - "before": "return min(40, max(6, elapsed))", - "after": "return min(40, max(5, elapsed))", - "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status.py -k test_fully_six_qcs_minimum", - "exit_code": 1, - "seconds": 49.08, - "failed_tests": [ - "FAILED tests/test_track_b_insured_status.py::test_fully_six_qcs_minimum[5-False]", - "FAILED tests/test_track_b_insured_status.py::test_fully_six_qcs_minimum[6-True]" - ], - "output": "FF [100%]\n=================================== FAILURES ===================================\n_____________________ test_fully_six_qcs_minimum[5-False] ______________________\n\ncount = 5, expected = False\n\n @pytest.mark.parametrize(\"count,expected\", [(5, False), (6, True)])\n def test_fully_six_qcs_minimum(count, expected):\n person = i.Person(date(2000, 2, 2))\n result = compute(\n person,\n date(2026, 12, 1),\n {2025: 4, 2026: count - 4},\n test=i.InsuredTest.FULLY,\n )\n> assert result.fully.required == 6\nE AssertionError: assert 5 == 6\nE + where 5 = StatusDecision(insured=True, qc_count_lower=5, qc_count_upper=5, required=5, window=(8000, 8001, 8002, 8003, 8004, 800... 8101, 8102, 8103, 8104, 8105, 8106, 8107), upper_assigned_quarters=(8100, 8101, 8102, 8103, 8104), upper_rule='fully').required\nE + where StatusDecision(insured=True, qc_count_lower=5, qc_count_upper=5, required=5, window=(8000, 8001, 8002, 8003, 8004, 800... 8101, 8102, 8103, 8104, 8105, 8106, 8107), upper_assigned_quarters=(8100, 8101, 8102, 8103, 8104), upper_rule='fully') = InsuredStatus(version='track-b-insured-v1', month=datetime.date(2026, 12, 1), fully=StatusDecision(insured=True, qc_co...101, 8102, 8103), 2026: (8104,)}), unknown_years=(), convention_years=mappingproxy({}), decided_despite_unknowns=False).fully\n\ntests/test_track_b_insured_status.py:767: AssertionError\n______________________ test_fully_six_qcs_minimum[6-True] ______________________\n\ncount = 6, expected = True\n\n @pytest.mark.parametrize(\"count,expected\", [(5, False), (6, True)])\n def test_fully_six_qcs_minimum(count, expected):\n person = i.Person(date(2000, 2, 2))\n result = compute(\n person,\n date(2026, 12, 1),\n {2025: 4, 2026: count - 4},\n test=i.InsuredTest.FULLY,\n )\n> assert result.fully.required == 6\nE AssertionError: assert 5 == 6\nE + where 5 = StatusDecision(insured=True, qc_count_lower=6, qc_count_upper=6, required=5, window=(8000, 8001, 8002, 8003, 8004, 800... 8102, 8103, 8104, 8105, 8106, 8107), upper_assigned_quarters=(8100, 8101, 8102, 8103, 8104, 8105), upper_rule='fully').required\nE + where StatusDecision(insured=True, qc_count_lower=6, qc_count_upper=6, required=5, window=(8000, 8001, 8002, 8003, 8004, 800... 8102, 8103, 8104, 8105, 8106, 8107), upper_assigned_quarters=(8100, 8101, 8102, 8103, 8104, 8105), upper_rule='fully') = InsuredStatus(version='track-b-insured-v1', month=datetime.date(2026, 12, 1), fully=StatusDecision(insured=True, qc_co...8102, 8103), 2026: (8104, 8105)}), unknown_years=(), convention_years=mappingproxy({}), decided_despite_unknowns=False).fully\n\ntests/test_track_b_insured_status.py:767: AssertionError\n=========================== short test summary info ============================\nFAILED tests/test_track_b_insured_status.py::test_fully_six_qcs_minimum[5-False]\nFAILED tests/test_track_b_insured_status.py::test_fully_six_qcs_minimum[6-True]\n2 failed, 46 deselected in 23.71s\n", - "restored": true - }, - { - "name": "currently_requirement_6_to_5", - "before": "_window(end, 13, periods, boundary),\n 6,", - "after": "_window(end, 13, periods, boundary),\n 5,", - "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status.py -k test_currently_six_qcs_boundary", - "exit_code": 1, - "seconds": 46.04, - "failed_tests": [ - "FAILED tests/test_track_b_insured_status.py::test_currently_six_qcs_boundary[5-False]", - "FAILED tests/test_track_b_insured_status.py::test_currently_six_qcs_boundary[6-True]" - ], - "output": "FF [100%]\n=================================== FAILURES ===================================\n___________________ test_currently_six_qcs_boundary[5-False] ___________________\n\ncount = 5, expected = False\n\n @pytest.mark.parametrize(\"count,expected\", [(5, False), (6, True)])\n def test_currently_six_qcs_boundary(count, expected):\n person = i.Person(date(1990, 2, 2))\n result = compute(\n person,\n date(2026, 12, 1),\n {2025: 4, 2026: count - 4},\n test=i.InsuredTest.CURRENTLY,\n )\n> assert result.currently.required == 6\nE AssertionError: assert 5 == 6\nE + where 5 = StatusDecision(insured=True, qc_count_lower=5, qc_count_upper=5, required=5, window=(8095, 8096, 8097, 8098, 8099, 810... 8103, 8104, 8105, 8106, 8107), upper_assigned_quarters=(8100, 8101, 8102, 8103, 8104), upper_rule='currently_6_of_13').required\nE + where StatusDecision(insured=True, qc_count_lower=5, qc_count_upper=5, required=5, window=(8095, 8096, 8097, 8098, 8099, 810... 8103, 8104, 8105, 8106, 8107), upper_assigned_quarters=(8100, 8101, 8102, 8103, 8104), upper_rule='currently_6_of_13') = InsuredStatus(version='track-b-insured-v1', month=datetime.date(2026, 12, 1), fully=None, currently=StatusDecision(ins...101, 8102, 8103), 2026: (8104,)}), unknown_years=(), convention_years=mappingproxy({}), decided_despite_unknowns=False).currently\n\ntests/test_track_b_insured_status.py:744: AssertionError\n___________________ test_currently_six_qcs_boundary[6-True] ____________________\n\ncount = 6, expected = True\n\n @pytest.mark.parametrize(\"count,expected\", [(5, False), (6, True)])\n def test_currently_six_qcs_boundary(count, expected):\n person = i.Person(date(1990, 2, 2))\n result = compute(\n person,\n date(2026, 12, 1),\n {2025: 4, 2026: count - 4},\n test=i.InsuredTest.CURRENTLY,\n )\n> assert result.currently.required == 6\nE AssertionError: assert 5 == 6\nE + where 5 = StatusDecision(insured=True, qc_count_lower=6, qc_count_upper=6, required=5, window=(8095, 8096, 8097, 8098, 8099, 810... 8104, 8105, 8106, 8107), upper_assigned_quarters=(8100, 8101, 8102, 8103, 8104, 8105), upper_rule='currently_6_of_13').required\nE + where StatusDecision(insured=True, qc_count_lower=6, qc_count_upper=6, required=5, window=(8095, 8096, 8097, 8098, 8099, 810... 8104, 8105, 8106, 8107), upper_assigned_quarters=(8100, 8101, 8102, 8103, 8104, 8105), upper_rule='currently_6_of_13') = InsuredStatus(version='track-b-insured-v1', month=datetime.date(2026, 12, 1), fully=None, currently=StatusDecision(ins...8102, 8103), 2026: (8104, 8105)}), unknown_years=(), convention_years=mappingproxy({}), decided_despite_unknowns=False).currently\n\ntests/test_track_b_insured_status.py:744: AssertionError\n=========================== short test summary info ============================\nFAILED tests/test_track_b_insured_status.py::test_currently_six_qcs_boundary[5-False]\nFAILED tests/test_track_b_insured_status.py::test_currently_six_qcs_boundary[6-True]\n2 failed, 46 deselected in 17.67s\n", - "restored": true - }, - { - "name": "regular_disability_20_to_19", - "before": "_window(end, 40, periods, boundary),\n 20,", - "after": "_window(end, 40, periods, boundary),\n 19,", - "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status.py -k test_disability_twenty_qcs_boundary", - "exit_code": 1, - "seconds": 75.26, - "failed_tests": [ - "FAILED tests/test_track_b_insured_status.py::test_disability_twenty_qcs_boundary[19-False]", - "FAILED tests/test_track_b_insured_status.py::test_disability_twenty_qcs_boundary[20-True]" - ], - "output": "FF [100%]\n=================================== FAILURES ===================================\n________________ test_disability_twenty_qcs_boundary[19-False] _________________\n\ncount = 19, expected = False\n\n @pytest.mark.parametrize(\"count,expected\", [(19, False), (20, True)])\n def test_disability_twenty_qcs_boundary(count, expected):\n person = i.Person(date(1990, 2, 2))\n counts = {2021: 4, 2022: 4, 2023: 4, 2024: 4, 2025: count - 16}\n result = compute(person, date(2026, 12, 1), counts)\n assert result.fully.insured\n> assert result.disability.required == 20\nE AssertionError: assert 19 == 20\nE + where 19 = StatusDecision(insured=True, qc_count_lower=19, qc_count_upper=19, required=19, window=(8068, 8069, 8070, 8071, 8072, ... 8089, 8090, 8091, 8092, 8093, 8094, 8095, 8096, 8097, 8098, 8099, 8100, 8101, 8102), upper_rule='disability_20_of_40').required\nE + where StatusDecision(insured=True, qc_count_lower=19, qc_count_upper=19, required=19, window=(8068, 8069, 8070, 8071, 8072, ... 8089, 8090, 8091, 8092, 8093, 8094, 8095, 8096, 8097, 8098, 8099, 8100, 8101, 8102), upper_rule='disability_20_of_40') = InsuredStatus(version='track-b-insured-v1', month=datetime.date(2026, 12, 1), fully=StatusDecision(insured=True, qc_co...5: (8100, 8101, 8102), 2026: ()}), unknown_years=(), convention_years=mappingproxy({}), decided_despite_unknowns=False).disability\n\ntests/test_track_b_insured_status.py:754: AssertionError\n_________________ test_disability_twenty_qcs_boundary[20-True] _________________\n\ncount = 20, expected = True\n\n @pytest.mark.parametrize(\"count,expected\", [(19, False), (20, True)])\n def test_disability_twenty_qcs_boundary(count, expected):\n person = i.Person(date(1990, 2, 2))\n counts = {2021: 4, 2022: 4, 2023: 4, 2024: 4, 2025: count - 16}\n result = compute(person, date(2026, 12, 1), counts)\n assert result.fully.insured\n> assert result.disability.required == 20\nE AssertionError: assert 19 == 20\nE + where 19 = StatusDecision(insured=True, qc_count_lower=20, qc_count_upper=20, required=19, window=(8068, 8069, 8070, 8071, 8072, ... 8090, 8091, 8092, 8093, 8094, 8095, 8096, 8097, 8098, 8099, 8100, 8101, 8102, 8103), upper_rule='disability_20_of_40').required\nE + where StatusDecision(insured=True, qc_count_lower=20, qc_count_upper=20, required=19, window=(8068, 8069, 8070, 8071, 8072, ... 8090, 8091, 8092, 8093, 8094, 8095, 8096, 8097, 8098, 8099, 8100, 8101, 8102, 8103), upper_rule='disability_20_of_40') = InsuredStatus(version='track-b-insured-v1', month=datetime.date(2026, 12, 1), fully=StatusDecision(insured=True, qc_co...00, 8101, 8102, 8103), 2026: ()}), unknown_years=(), convention_years=mappingproxy({}), decided_despite_unknowns=False).disability\n\ntests/test_track_b_insured_status.py:754: AssertionError\n=========================== short test summary info ============================\nFAILED tests/test_track_b_insured_status.py::test_disability_twenty_qcs_boundary[19-False]\nFAILED tests/test_track_b_insured_status.py::test_disability_twenty_qcs_boundary[20-True]\n2 failed, 46 deselected in 44.47s\n", - "restored": true - }, - { - "name": "young_half_quarters_to_one_third", - "before": "max(6, len(elapsed) // 2)", - "after": "max(6, len(elapsed) // 3)", - "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status.py -k test_fred_brown_35_quarters_require_17_poms_140_example_1", - "exit_code": 1, - "seconds": 38.1, - "failed_tests": [ - "FAILED tests/test_track_b_insured_status.py::test_fred_brown_35_quarters_require_17_poms_140_example_1" - ], - "output": "F [100%]\n=================================== FAILURES ===================================\n__________ test_fred_brown_35_quarters_require_17_poms_140_example_1 ___________\n\n def test_fred_brown_35_quarters_require_17_poms_140_example_1():\n person = i.Person(date(1958, 5, 13), disability_onset=date(1988, 1, 15))\n result = compute(\n person,\n date(1988, 1, 1),\n {1980: 4, 1981: 4, 1982: 4, 1983: 4, 1984: 1},\n )\n> assert result.disability.required == 17\nE AssertionError: assert 11 == 17\nE + where 11 = StatusDecision(insured=True, qc_count_lower=17, qc_count_upper=17, required=11, window=(7918, 7919, 7920, 7921, 7922, ...922, 7923, 7924, 7925, 7926, 7927, 7928, 7929, 7930, 7931, 7932, 7933, 7934, 7935, 7936), upper_rule='under31_special').required\nE + where StatusDecision(insured=True, qc_count_lower=17, qc_count_upper=17, required=11, window=(7918, 7919, 7920, 7921, 7922, ...922, 7923, 7924, 7925, 7926, 7927, 7928, 7929, 7930, 7931, 7932, 7933, 7934, 7935, 7936), upper_rule='under31_special') = InsuredStatus(version='track-b-insured-v1', month=datetime.date(1988, 1, 1), fully=StatusDecision(insured=True, qc_cou...), 1986: (), 1987: (), 1988: ()}), unknown_years=(), convention_years=mappingproxy({}), decided_despite_unknowns=False).disability\n\ntests/test_track_b_insured_status.py:91: AssertionError\n=========================== short test summary info ============================\nFAILED tests/test_track_b_insured_status.py::test_fred_brown_35_quarters_require_17_poms_140_example_1\n1 failed, 47 deselected in 22.15s\n", - "restored": true - } - ], - "sha256_after": "b6bf989787bd465e080a435d77a178cee9ef861535eac190ab7fca9bd1033fc8", - "restored": true, - "verification": [ - { - "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status.py -x", - "result": "Initial suite:30passed234.26s; after DLI/world optimization and subsequent examples:42passed32.10s." - }, - { - "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status.py", - "result": "46passed34.70s before finaltwo registry tests; initial48-case run47passed1failed (FRAcompletionhad39ratherthan40QCs beforeFRAquarter; fixedinventedcompletionadds2009)." - }, - { - "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status.py -k \"dli_fra_cap or age_attainment\"", - "result": "2passed46deselected29.92s aftercorrectedcompletion." - }, - { - "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/estimates/test_birth_evidence_artifact.py -k \"not test_artifact_rebuild_reproduces\"", - "result": "13passed92.91s." - }, - { - "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m black -l 79 --check tests/test_track_b_insured_status.py scripts/first_estimates_birth_evidence.py tests/estimates/test_birth_evidence_artifact.py", - "result": "3files would be left unchanged." - }, - { - "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m ruff check tests/test_track_b_insured_status.py scripts/first_estimates_birth_evidence.py tests/estimates/test_birth_evidence_artifact.py", - "result": "Allchecks passed." - }, - { - "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_gross_benefits_fix_round_15_collections.py tests/test_track_b_gross_benefits_fix_round_15_arguments.py", - "result": "575 passed,36 failed in96.03s; all failures were missing insured_status COMPUTE/EVALUATE fixture map entries, fixed locally in arguments test." - }, - { - "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_gross_benefits_fix_round_15_arguments.py -k \"insured_status or CoverageYear or DisabilityPeriod or Person\"", - "result": "36 passed,272 deselected in11.03s." - }, - { - "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent POPULACE_DYNAMICS_EPUF_DIR=/nonexistent PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_gross_benefits_fix_round_15_collections.py tests/test_track_b_gross_benefits_fix_round_15_arguments.py", - "result": "611 passed in52.69s." - }, - { - "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m black -l79 tests/test_track_b_gross_benefits_fix_round_15_arguments.py", - "result": "1 file unchanged." - }, - { - "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m ruff check tests/test_track_b_gross_benefits_fix_round_15_arguments.py", - "result": "All checks passed." - } - ] - } -} diff --git a/tests/data/track_b/insured_status_sources/README.md b/tests/data/track_b/insured_status_sources/README.md index d7e588bad..df89d631f 100644 --- a/tests/data/track_b/insured_status_sources/README.md +++ b/tests/data/track_b/insured_status_sources/README.md @@ -4,7 +4,7 @@ Verification class: statutory conformance. These public statutory sources support invented cases and published examples only. They admit no population, behavioral or forecast claim. -`manifest.json` pins all 45 captures with their URL, UTC retrieval +`manifest.json` pins all 48 captures with their URL, UTC retrieval time, byte count, SHA-256 and capture format. POMS entries additionally retain the exact transmittal and page date. The staging log was removed only after all original byte counts and hashes were verified. The source @@ -17,8 +17,8 @@ attachments. The capture formats follow the gross-benefit manifest, with one addition: - `http_body`: complete decoded HTTP response, unchanged. This includes - all 37 POMS sections, their table of contents and eCFR subpart B as of - 2026-10-07. + all 37 POMS sections, their table of contents, eCFR subpart B and + sections 404.315, 404.320 and 404.321 as of 2026-10-07. - `browser_text`: staged OACT quarter-of-coverage page text; `served_bodies` records the original response identity. Its chart includes 2027. - `http_text_excerpt`: relevant paragraphs of staged LII bodies, after @@ -46,6 +46,7 @@ The capture formats follow the gross-benefit manifest, with one addition: | RS 00301.470, .475, .480, .600 | Deemed veterans, earned-basis wages, pre-1956 alternative test and vow-of-poverty refusals | | RS 00301.800 and its exhibit | Exhibit shell, plus the exhibit's 38-row cohort table, checked row by row | | 20 CFR 404 subpart B | Statutory rules, worked examples and the 404.115 cohort chart | +| 20 CFR 404.315, .320, .321 | Waiting-period insured prerequisite, administrative establishment, favorable disregard and first insured-quarter period start | | 42 USC 413, 414, 416, 423 | Act 213, 214, 216(i)/(l), 223(c)(1) | | SSA OACT QC page | Independent 1978-2027 chart and 2027 determination | @@ -92,10 +93,29 @@ Examples 2, 5, 6 and 7 expressly say the worker never received an SSN. The public declaration represents this with `ssn_never_assigned=True` and returns the named alien-worker refusal, retained in the denominator. It does not mistake this valid unsupported fact for a missing required date. +RS 00301.102 B.1 exempts workers whose first SSN was assigned before +January 1, 2004, including nonwork SSNs. B.3 expressly applies section 211 +to workers not yet assigned an SSN based on their true identity. B.4.b +allows certain work-authorized workers without an SSN to meet the +additional requirement; it does not exempt every unassigned worker. RS 00301.120 distinguishes onset/freeze protection from the later DIB waiting period. A person-month insured-status query does not itself adjudicate an application, establish a freeze or determine cash entitlement. +Sections 404.320(b) and 416(i)(2)(A)-(B) require administrative facts in +addition to medical onset: an application and a sufficiently long period, +with the statutory DIB-entitlement alternative. Section 404.321(a) starts +an established period at medical onset only when insured then; otherwise +it starts at the first later insured quarter. Section 404.315(a)(4) +requires the waiting period to start in a month both disabled and insured. +Its waiting-period start therefore cannot precede that first insured +quarter and cannot produce an earlier elapsed-year endpoint. + +RS 00301.140 example 2 permits later insured status but supplies no later +earnings history or qualifying date. The additional registry entry keeps +Sam White's published birth and onset dates and labels its completion of +three QCs in each of 1983 and 1984 as invented. That completion supplies +five assignable QCs at the onset quarter, 1984Q2, and six at 1984Q3. The registry separates helper arithmetic from public support: the fiscal and short-tax-year allocation examples execute private allocation helpers, diff --git a/tests/data/track_b/insured_status_sources/ecfr_20cfr404_315.xml b/tests/data/track_b/insured_status_sources/ecfr_20cfr404_315.xml new file mode 100644 index 000000000..031476cae --- /dev/null +++ b/tests/data/track_b/insured_status_sources/ecfr_20cfr404_315.xml @@ -0,0 +1,14 @@ + + +§ 404.315 Who is entitled to disability benefits? +

(a) General. You are entitled to disability benefits while disabled before attaining full retirement age as defined in § 404.409 if—

+

(1) You have enough social security earnings to be insured for disability, as described in § 404.130;

+

(2) You apply;

+

(3) You have a disability, as defined in § 404.1505, or you are not disabled, but you had a disability that ended within the 12-month period before the month you applied; and

+

(4) You have been disabled for 5 full consecutive months or no waiting period is required. The 5-month waiting period begins with a month in which you were both insured for disability and disabled. Your waiting period can begin no earlier than the 17th month before the month you apply—no matter how long you were disabled before then. No waiting period is required if:

+

(i) You were previously entitled to disability benefits or to a period of disability under § 404.320 any time within 5 years of the month you again became disabled; or

+

(ii) You have been medically determined to have amyotrophic lateral sclerosis, and we approved your application for disability insurance benefits on or after July 23, 2020.

+

(b) [Reserved]

+[44 FR 34481, June 15, 1979, as amended at 48 FR 21930, May 16, 1983; 51 FR 10616, Mar. 28, 1986; 51 FR 16166, May 1, 1986; 53 FR 43681, Oct. 28, 1988; 57 FR 30119, July 8, 1992; 60 FR 8145, Feb. 10, 1995; 68 FR 4704, Jan. 30, 2003; 86 FR 48021, Aug. 27, 2021; 91 FR 16829, Apr. 3, 2026] + +
diff --git a/tests/data/track_b/insured_status_sources/ecfr_20cfr404_320.xml b/tests/data/track_b/insured_status_sources/ecfr_20cfr404_320.xml new file mode 100644 index 000000000..736a82613 --- /dev/null +++ b/tests/data/track_b/insured_status_sources/ecfr_20cfr404_320.xml @@ -0,0 +1,12 @@ + + +§ 404.320 Who is entitled to a period of disability. +

(a) General. A period of disability is a continuous period of time during which you are disabled. If you become disabled, you may apply to have our records show how long your disability lasts. You may do this even if you do not qualify for disability benefits. If we establish a period of disability for you, the months in that period of time will not be counted in figuring your average earnings. If benefits payable on your earnings record would be denied or reduced because of a period of disability, the period of disability will not be taken into consideration.

+

(b) Who is entitled. You are entitled to a period of disability if you meet all the following conditions:

+

(1) You have or had a disability as defined in § 404.1505.

+

(2) You are insured for disability, as defined in § 404.130 in the calendar quarter in which you became disabled, or in a later calendar quarter in which you were disabled.

+

(3) You file an application while disabled, or no later than 12 months after the month in which your period of disability ended. If you were unable to apply within the 12-month period after your period of disability ended because of a physical or mental condition as described in § 404.322, you may apply not more than 36 months after the month your disability ended.

+

(4) At least 5 consecutive months go by from the month in which your period of disability begins and before the month in which it would end.

+[44 FR 34481, June 15, 1979, as amended at 48 FR 21930, May 16, 1983; 51 FR 10616, Mar. 28, 1986] + +
diff --git a/tests/data/track_b/insured_status_sources/ecfr_20cfr404_321.xml b/tests/data/track_b/insured_status_sources/ecfr_20cfr404_321.xml new file mode 100644 index 000000000..6f16947be --- /dev/null +++ b/tests/data/track_b/insured_status_sources/ecfr_20cfr404_321.xml @@ -0,0 +1,12 @@ + + +§ 404.321 When a period of disability begins and ends. +

(a) When a period of disability begins. Your period of disability begins on the day your disability begins if you are insured for disability on that day. If you are not insured for disability on that day, your period of disability will begin on the first day of the first calendar quarter after your disability began in which you become insured for disability. Your period of disability may not begin after you have attained full retirement age as defined in § 404.409.

+

(b) When disability ended before December 1, 1980. Your period of disability ends on the last day of the month before the month in which you become 65 years old or, if earlier, the last day of the second month following the month in which your disability ended.

+

(c) When disability ends after November 1980. Your period of disability ends with the close of whichever of the following is the earliest—

+

(1) The month before the month in which you attain full retirement age as defined in § 404.409.

+

(2) The month immediately preceding your termination month (§ 404.325); or

+

(3) If you perform substantial gainful activity during the reentitlement period described in § 404.1592a, the last month for which you received benefits.

+[49 FR 22271, May 29, 1984, as amended at 60 FR 8145, Feb. 10, 1995; 65 FR 42782, July 11, 2000; 68 FR 4704, Jan. 30, 2003; 91 FR 16829, Apr. 3, 2026] + +
diff --git a/tests/data/track_b/insured_status_sources/manifest.json b/tests/data/track_b/insured_status_sources/manifest.json index 8baf37a17..16375846b 100644 --- a/tests/data/track_b/insured_status_sources/manifest.json +++ b/tests/data/track_b/insured_status_sources/manifest.json @@ -628,6 +628,36 @@ "sha256": "65d94bae34becf54cf40e361cb6fb5668883f164efdff371122e8d2b9717efe3" } ] + }, + { + "file": "ecfr_20cfr404_315.xml", + "bytes": 1833, + "sha256": "cd2ca75f18f5ddf3779fb01ee0d25998e1411fc03e2f95de8e4b2d7c6ebebf26", + "id": "ecfr_20cfr404_315", + "citation": "20 CFR 404.315 (eCFR, as of 2026-10-07)", + "url": "https://www.ecfr.gov/api/versioner/v1/full/2026-10-07/title-20.xml?part=404§ion=404.315", + "retrieved_at_utc": "2026-10-25T07:10:45Z", + "capture": "http_body" + }, + { + "file": "ecfr_20cfr404_320.xml", + "bytes": 1897, + "sha256": "b0b0e6940b95801c73eaac1f61922b9fbd9f41dc20867bed84f6667d98f990c9", + "id": "ecfr_20cfr404_320", + "citation": "20 CFR 404.320 (eCFR, as of 2026-10-07)", + "url": "https://www.ecfr.gov/api/versioner/v1/full/2026-10-07/title-20.xml?part=404§ion=404.320", + "retrieved_at_utc": "2026-10-25T07:10:54Z", + "capture": "http_body" + }, + { + "file": "ecfr_20cfr404_321.xml", + "bytes": 1737, + "sha256": "b10d89b4ebbc8b978959e11b098612a5d68bc29620b50ed8b5a06a76c44e5c24", + "id": "ecfr_20cfr404_321", + "citation": "20 CFR 404.321 (eCFR, as of 2026-10-07)", + "url": "https://www.ecfr.gov/api/versioner/v1/full/2026-10-07/title-20.xml?part=404§ion=404.321", + "retrieved_at_utc": "2026-10-25T07:10:54Z", + "capture": "http_body" } ] } diff --git a/tests/test_track_b_gross_benefits_fix_round_13_audit.py b/tests/test_track_b_gross_benefits_fix_round_13_audit.py index a9167d4fd..363c11d68 100644 --- a/tests/test_track_b_gross_benefits_fix_round_13_audit.py +++ b/tests/test_track_b_gross_benefits_fix_round_13_audit.py @@ -370,7 +370,14 @@ def _declaration_cases(): cases[type(value).__name__] = value cases.update( { - "Person": insured.Person(date(2000, 1, 2)), + "Person": insured.Person( + date(2000, 1, 2), + prior_disability_periods_provenance=insured.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=insured.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=insured.EarningsProvenance.OBSERVED, + ), "CoverageYear": insured.CoverageYear( insured.EarningsProvenance.OBSERVED, qc_count=4 ), @@ -478,7 +485,14 @@ def _sealed_samples(): 2026, grace.GraceYearState(), [grace.GraceMonth()] * 12 ) samples["RecomputationDecision"] = c.recomputation_decision(1, 2) - person = insured.Person(date(2026, 1, 2)) + person = insured.Person( + date(2026, 1, 2), + prior_disability_periods_provenance=insured.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=insured.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=insured.EarningsProvenance.OBSERVED, + ) years = { 2026: insured.CoverageYear( insured.EarningsProvenance.OBSERVED, qc_count=0 diff --git a/tests/test_track_b_gross_benefits_fix_round_15_arguments.py b/tests/test_track_b_gross_benefits_fix_round_15_arguments.py index c95b07353..8f156e080 100644 --- a/tests/test_track_b_gross_benefits_fix_round_15_arguments.py +++ b/tests/test_track_b_gross_benefits_fix_round_15_arguments.py @@ -34,7 +34,14 @@ def _insured_status(*, refused=False): return insured.insured_status( - insured.Person(date(2026, 1, 2)), + insured.Person( + date(2026, 1, 2), + prior_disability_periods_provenance=insured.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=insured.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=insured.EarningsProvenance.OBSERVED, + ), { 2026: insured.CoverageYear( insured.EarningsProvenance.OBSERVED, qc_count=0 diff --git a/tests/test_track_b_input_schema.py b/tests/test_track_b_input_schema.py index 0eb530d33..458feed56 100644 --- a/tests/test_track_b_input_schema.py +++ b/tests/test_track_b_input_schema.py @@ -471,7 +471,14 @@ def public_world(): layer: (EVALUATE[layer]("valid", 1, COMPUTE[layer]),) for layer in LAYERS } - insured_person = insured.Person(date(2000, 1, 2)) + insured_person = insured.Person( + date(2000, 1, 2), + prior_disability_periods_provenance=insured.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=insured.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=insured.EarningsProvenance.OBSERVED, + ) insured_years = { year: insured.CoverageYear( insured.EarningsProvenance.OBSERVED, qc_count=4 diff --git a/tests/test_track_b_insured_status.py b/tests/test_track_b_insured_status.py index 680515bcc..8e95db22f 100644 --- a/tests/test_track_b_insured_status.py +++ b/tests/test_track_b_insured_status.py @@ -69,7 +69,14 @@ def statuses(result): def test_version_and_explicit_zero_history(): - person = i.Person(date(1990, 5, 2)) + person = i.Person( + date(1990, 5, 2), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) result = compute(person, date(2026, 12, 1)) assert result.version == "track-b-insured-v1" assert not any(statuses(result)) @@ -83,7 +90,15 @@ def test_version_and_explicit_zero_history(): def test_fred_brown_35_quarters_require_17_poms_140_example_1(): - person = i.Person(date(1958, 5, 13), disability_onset=date(1988, 1, 15)) + person = i.Person( + date(1958, 5, 13), + disability_onset=date(1988, 1, 15), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) result = compute( person, date(1988, 1, 1), @@ -97,7 +112,15 @@ def test_fred_brown_35_quarters_require_17_poms_140_example_1(): def test_sam_white_6_in_12_poms_140_example_2(): - person = i.Person(date(1961, 8, 20), disability_onset=date(1984, 4, 12)) + person = i.Person( + date(1961, 8, 20), + disability_onset=date(1984, 4, 12), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) result = compute(person, date(1984, 4, 1), {1982: 4, 1983: 2}) assert result.disability.required == 6 assert result.disability.window == tuple( @@ -116,7 +139,15 @@ def test_sam_white_6_in_12_poms_140_example_2(): ids=["mary-example-3", "mary-example-4", "mary-example-5-moveable"], ) def test_mary_smith_special_window_poms_140_examples_3_to_5(counts, expected): - person = i.Person(date(1964, 11, 15), disability_onset=date(1985, 8, 30)) + person = i.Person( + date(1964, 11, 15), + disability_onset=date(1985, 8, 30), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) result = compute(person, date(1985, 8, 1), counts) assert result.disability.required == 6 assert result.disability.window == tuple( @@ -126,7 +157,14 @@ def test_mary_smith_special_window_poms_140_examples_3_to_5(counts, expected): def test_dli_1990_june_poms_148_example(): - person = i.Person(date(1954, 3, 9)) + person = i.Person( + date(1954, 3, 9), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) counts = { 1973: 2, 1975: 4, @@ -155,6 +193,11 @@ def test_calvin_hill_blind_clock_poms_150_example(): date(1957, 7, 12), disability_onset=date(1957, 7, 12), statutory_blindness=True, + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, ) counts = {1977: 2, 1982: 1, 1983: 1, 1985: 1, 1986: 2} first = history(person, date(1986, 1, 1), counts) @@ -196,7 +239,16 @@ def test_fully_requirement_differential_cfr_404_115_every_captured_row(): if not cell: continue assert i.fully_insured_requirement( - i.Person(birth, sex=sex), date(2026, 12, 1) + i.Person( + birth, + sex=sex, + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ), + date(2026, 12, 1), ) == int(cell) tested += 1 assert tested >= 140 @@ -244,7 +296,15 @@ def test_fully_requirement_differential_poms_rs_00301_800_exhibit(): for sex, birth in cohorts: age = 65 if sex is i.Sex.MALE and birth < date(1913, 1, 2) else 62 month = date(birth.year + age + 1, 12, 1) - person = i.Person(birth, sex=sex) + person = i.Person( + birth, + sex=sex, + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) assert i.fully_insured_requirement(person, month) == required, ( men, women, @@ -262,6 +322,11 @@ def test_fully_requirement_differential_poms_rs_00301_800_exhibit(): date(1929, 7, 1), sex=i.Sex.FEMALE, death_date=date(year, 7, 1), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, ) assert ( i.fully_insured_requirement(person, date(year, 12, 1)) @@ -272,7 +337,14 @@ def test_fully_requirement_differential_poms_rs_00301_800_exhibit(): def test_elapsed_years_from_birth_not_projection_entry(): - person = i.Person(date(1980, 2, 2)) + person = i.Person( + date(1980, 2, 2), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) assert i.fully_insured_requirement(person, date(2026, 1, 1)) == 24 result = compute(person, date(2026, 1, 1), {2024: 4, 2025: 4, 2026: 1}) assert not result.fully.insured @@ -280,7 +352,14 @@ def test_elapsed_years_from_birth_not_projection_entry(): def test_fully_requirement_excludes_partial_disability_years_cfr_example(): - plain = i.Person(date(1935, 1, 2)) + plain = i.Person( + date(1935, 1, 2), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) frozen = replace( plain, prior_disability_periods=( @@ -296,7 +375,14 @@ def test_fully_requirement_excludes_partial_disability_years_cfr_example(): def test_unknown_is_never_zero_and_named_refusal_stays_in_denominator(): - person = i.Person(date(2000, 2, 2)) + person = i.Person( + date(2000, 2, 2), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) month = date(2026, 12, 1) years = history(person, month, {2025: 4}) years[2024] = declared(provenance=i.EarningsProvenance.UNKNOWN) @@ -320,7 +406,14 @@ def test_unknown_is_never_zero_and_named_refusal_stays_in_denominator(): def test_decided_despite_unknown_reports_range_and_unknown_years(): - person = i.Person(date(2000, 2, 2)) + person = i.Person( + date(2000, 2, 2), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) month = date(2026, 12, 1) years = history(person, month, {2025: 4, 2026: 4}) years[2024] = declared(provenance=i.EarningsProvenance.UNKNOWN) @@ -334,7 +427,14 @@ def test_decided_despite_unknown_reports_range_and_unknown_years(): def test_missing_year_and_provenance_are_input_errors(): - person = i.Person(date(2000, 2, 2)) + person = i.Person( + date(2000, 2, 2), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) month = date(2026, 12, 1) years = history(person, month) del years[2010] @@ -364,7 +464,14 @@ def test_ambiguous_or_malformed_direct_coverage_is_input_error(change): def test_before_1978_direct_qcs_require_quarter_flags(): - person = i.Person(date(1950, 2, 2)) + person = i.Person( + date(1950, 2, 2), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) month = date(1977, 12, 1) years = history(person, month) years[1977] = i.CoverageYear(i.EarningsProvenance.OBSERVED, qc_count=2) @@ -373,7 +480,14 @@ def test_before_1978_direct_qcs_require_quarter_flags(): def test_totalization_is_named_refusal_and_empty_changes_nothing(): - person = i.Person(date(1990, 2, 2)) + person = i.Person( + date(1990, 2, 2), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) month = date(2026, 12, 1) years = history(person, month) assert i.insured_status(person, years, month) == i.insured_status( @@ -392,7 +506,14 @@ def test_totalization_is_named_refusal_and_empty_changes_nothing(): def test_exit_freezes_credits_but_recent_work_clocks_continue(): - person = i.Person(date(1980, 2, 2)) + person = i.Person( + date(1980, 2, 2), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) exit_month = date(2020, 12, 1) counts = {year: 4 for year in range(2011, 2021)} years = history(person, exit_month, counts) @@ -415,7 +536,14 @@ def test_exit_freezes_credits_but_recent_work_clocks_continue(): def test_results_outcomes_and_denominators_are_sealed(): - person = i.Person(date(2000, 2, 2)) + person = i.Person( + date(2000, 2, 2), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) result = compute(person, date(2026, 12, 1)) outcome = i.evaluate_insured_status("sealed", Fraction(1), lambda: result) denominator = count_family_outcomes((outcome,)) @@ -434,7 +562,14 @@ def test_results_outcomes_and_denominators_are_sealed(): def test_property_status_and_dli_monotone_in_quarters( counts, index, birth_year ): - person = i.Person(date(birth_year, 2, 2)) + person = i.Person( + date(birth_year, 2, 2), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) month = date(2026, 12, 1) lower = dict(zip(range(2017, 2027), counts, strict=True)) upper = dict(lower) @@ -456,7 +591,14 @@ def test_property_status_and_dli_monotone_in_quarters( st.lists(st.integers(0, 4), min_size=10, max_size=10), st.integers(0, 9) ) def test_property_unknown_bounds_cover_every_filling(counts, index): - person = i.Person(date(1990, 2, 2)) + person = i.Person( + date(1990, 2, 2), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) month = date(2026, 12, 1) years = history( person, month, dict(zip(range(2017, 2027), counts, strict=True)) @@ -511,7 +653,14 @@ def test_property_unknown_bounds_cover_every_filling(counts, index): @PROPERTY @given(st.lists(st.integers(0, 4), min_size=10, max_size=10)) def test_property_convention_equal_amounts_and_order_independence(counts): - person = i.Person(date(1990, 2, 2)) + person = i.Person( + date(1990, 2, 2), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) month = date(2026, 12, 1) years = history( person, month, dict(zip(range(2017, 2027), counts, strict=True)) @@ -542,7 +691,14 @@ def test_property_convention_equal_amounts_and_order_independence(counts): @PROPERTY @given(st.integers(1930, 2000), st.integers(1, 4)) def test_property_windows_and_blindness_rule(birth_year, quarter): - person = i.Person(date(birth_year, 2, 2)) + person = i.Person( + date(birth_year, 2, 2), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) month = date(2026, quarter * 3, 1) counts = {year: 4 for year in range(max(birth_year, 1990), 2026)} ordinary = compute(person, month, counts) @@ -563,7 +719,14 @@ def test_property_windows_and_blindness_rule(birth_year, quarter): def test_property_input_errors_are_atomic_before_refusal( weight, missing_offset ): - person = i.Person(date(2000, 2, 2)) + person = i.Person( + date(2000, 2, 2), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) month = date(2026, 12, 1) years = history(person, month) del years[2000 + missing_offset] @@ -580,7 +743,14 @@ def test_property_input_errors_are_atomic_before_refusal( @PROPERTY @given(st.integers(0, 100), st.integers(0, 100)) def test_property_refusal_denominator_conserves_rows_and_weights(left, right): - person = i.Person(date(2000, 2, 2)) + person = i.Person( + date(2000, 2, 2), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) month = date(2026, 12, 1) years = history(person, month) supported = i.evaluate_insured_status( @@ -618,7 +788,14 @@ def test_property_refusal_denominator_conserves_rows_and_weights(left, right): def test_property_disability_period_exclusion_never_adds_qcs( start_year, counts ): - person = i.Person(date(1980, 2, 2)) + person = i.Person( + date(1980, 2, 2), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) frozen = replace( person, prior_disability_periods=( @@ -643,7 +820,14 @@ def test_property_disability_period_exclusion_never_adds_qcs( def test_unknown_upper_bound_respects_exit_quarter(): - person = i.Person(date(2000, 2, 2)) + person = i.Person( + date(2000, 2, 2), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) exit_month = date(2026, 4, 1) years = history(person, exit_month, {2024: 4, 2025: 4}) years[2026] = declared(provenance=i.EarningsProvenance.UNKNOWN) @@ -659,7 +843,14 @@ def test_unknown_upper_bound_respects_exit_quarter(): def test_special_insured_quarter_before_31_boundary(): - person = i.Person(date(1995, 11, 15)) + person = i.Person( + date(1995, 11, 15), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) counts = {2018: 4, 2019: 4, 2020: 4, 2021: 4, 2022: 3} before = compute(person, date(2026, 7, 1), counts) attainment_quarter = compute(person, date(2026, 10, 1), counts) @@ -678,6 +869,11 @@ def test_joseph_subsequent_poms_140_example_6_endpoint_erratum(): date(1981, 2, 3), date(1982, 12, 31), special_insured=True ), ), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, ) result = compute( person, @@ -726,6 +922,11 @@ def test_subsequent_under31_poms_140_examples_7_and_8( prior_disability_periods=( i.DisabilityPeriod(start, end, special_insured=True), ), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, ) result = compute(person, onset.replace(day=1), counts) assert result.disability.insured @@ -743,6 +944,11 @@ def test_sam_subsequent_poms_140_example_9_favorable_disregard_erratum(): date(1985, 12, 16), date(1989, 12, 31), special_insured=True ), ), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, ) counts = {1983: 2, 1984: 4, 1988: 4, 1989: 4, 1992: 4, 1993: 4} result = compute(person, date(1993, 5, 1), counts) @@ -774,6 +980,11 @@ def test_property_subsequent_special_and_dli_monotonic(year, count): date(1975, 5, 16), date(1978, 12, 31), special_insured=True ), ), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, ) month = date(1983, 6, 1) lower = { @@ -804,7 +1015,14 @@ def test_property_subsequent_special_and_dli_monotonic(year, count): @pytest.mark.parametrize("count,expected", [(5, False), (6, True)]) def test_currently_six_qcs_boundary(count, expected): - person = i.Person(date(1990, 2, 2)) + person = i.Person( + date(1990, 2, 2), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) result = compute( person, date(2026, 12, 1), @@ -817,7 +1035,14 @@ def test_currently_six_qcs_boundary(count, expected): @pytest.mark.parametrize("count,expected", [(19, False), (20, True)]) def test_disability_twenty_qcs_boundary(count, expected): - person = i.Person(date(1990, 2, 2)) + person = i.Person( + date(1990, 2, 2), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) counts = {2021: 4, 2022: 4, 2023: 4, 2024: 4, 2025: count - 16} result = compute(person, date(2026, 12, 1), counts) assert result.fully.insured @@ -827,7 +1052,14 @@ def test_disability_twenty_qcs_boundary(count, expected): @pytest.mark.parametrize("count,expected", [(5, False), (6, True)]) def test_fully_six_qcs_minimum(count, expected): - person = i.Person(date(2000, 2, 2)) + person = i.Person( + date(2000, 2, 2), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) result = compute( person, date(2026, 12, 1), @@ -841,7 +1073,15 @@ def test_fully_six_qcs_minimum(count, expected): def test_guinness_lis_poms_120_freeze_protects_onset_status(): # The capture supplies insured status at onset, not a DOB/full record. # This invented completion realizes its declared 20-QC premise. - person = i.Person(date(1940, 2, 2), disability_onset=date(1977, 12, 15)) + person = i.Person( + date(1940, 2, 2), + disability_onset=date(1977, 12, 15), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) counts = {year: 4 for year in range(1973, 1978)} onset = compute(person, date(1977, 12, 1), counts) waiting = compute(person, date(1987, 2, 1), counts) @@ -939,6 +1179,11 @@ def test_subsequent_over31_poms_147_examples( prior_disability_periods=( i.DisabilityPeriod(start, end, special_insured=True), ), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, ) years = history(person, date(1983, 6, 1)) for year, pattern in patterns.items(): @@ -973,6 +1218,11 @@ def test_sam_favorable_disregard_counterexample_one_qc_boundary(): date(1985, 12, 16), date(1989, 12, 31), special_insured=True ), ), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, ) counts = {1983: 1, 1984: 4, 1988: 4, 1989: 4, 1992: 4, 1993: 2} below = compute(person, date(1993, 5, 1), counts) @@ -986,7 +1236,14 @@ def test_sam_favorable_disregard_counterexample_one_qc_boundary(): def test_dli_fra_cap_poms_148_november_2019(): # The source specifies FRA11/2019, not a birth date or earnings record. # This invented completion has at least40QCs before that FRA quarter. - person = i.Person(date(1953, 11, 2)) + person = i.Person( + date(1953, 11, 2), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) result = compute( person, date(2019, 12, 1), {year: 4 for year in range(2009, 2020)} ) diff --git a/tests/test_track_b_insured_status_contract.py b/tests/test_track_b_insured_status_contract.py index 94cf87729..c4308cd26 100644 --- a/tests/test_track_b_insured_status_contract.py +++ b/tests/test_track_b_insured_status_contract.py @@ -20,7 +20,14 @@ def test_future_exit_does_not_remove_dli_censoring(): - person = i.Person(date(1980, 1, 2)) + person = i.Person( + date(1980, 1, 2), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) month = date(2026, 1, 1) years = history(person, month, {y: 4 for y in range(2015, 2025)}) result = i.insured_status(person, years, month) @@ -32,7 +39,15 @@ def test_future_exit_does_not_remove_dli_censoring(): def test_currently_insured_uses_death_quarter_after_death(): - person = i.Person(date(1980, 1, 2), death_date=date(2020, 12, 15)) + person = i.Person( + date(1980, 1, 2), + death_date=date(2020, 12, 15), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) years = history(person, date(2020, 12, 1), {2019: 4, 2020: 4}) at_death = i.insured_status(person, years, date(2020, 12, 1)) later = i.insured_status(person, years, date(2026, 1, 1)) @@ -45,7 +60,15 @@ def test_currently_insured_uses_death_quarter_after_death(): "field", ["rib_entitlement_month", "dib_entitlement_month"] ) def test_currently_insured_preserves_actual_entitlement_event(field): - person = i.Person(date(1960, 1, 2), **{field: date(2020, 12, 1)}) + person = i.Person( + date(1960, 1, 2), + **{field: date(2020, 12, 1)}, + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) month = date(2026, 1, 1) years = history(person, month, {2019: 4, 2020: 4}) actual = i.insured_status(person, years, month) @@ -62,6 +85,11 @@ def test_currently_insured_accepts_any_statutory_event(): dib_entitlement_month=date(2000, 12, 1), rib_entitlement_month=date(2022, 12, 1), death_date=date(2025, 12, 10), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, ) month = date(2026, 1, 1) years = history(person, month, {1999: 4, 2000: 4}) @@ -69,14 +97,19 @@ def test_currently_insured_accepts_any_statutory_event(): assert result.currently.insured assert result.currently.window[-1] == 2000 * 4 + 3 - # RS00301.110 excludes prior periods, not the period containing the - # historical entitlement event itself. Its later end is known here. + # 404.120(b) and RS00301.110 exclude every established period that + # intersects the window, including the entitlement event's own period. person = i.Person( date(1960, 2, 2), dib_entitlement_month=date(2000, 7, 1), prior_disability_periods=( i.DisabilityPeriod(date(2000, 1, 1), date(2005, 12, 31)), ), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, ) month = date(2010, 1, 1) years = history( @@ -85,15 +118,23 @@ def test_currently_insured_accepts_any_statutory_event(): result = i.insured_status( person, years, month, test=i.InsuredTest.CURRENTLY ) - assert not result.currently.insured - assert result.currently.qc_count_lower == 4 + assert result.currently.insured + assert result.currently.qc_count_lower == 6 @pytest.mark.parametrize("condition", list(i.CoverageCondition)) def test_each_declared_specialist_condition_has_named_retained_refusal( condition, ): - person = i.Person(date(1980, 2, 2), conditions=(condition,)) + person = i.Person( + date(1980, 2, 2), + conditions=(condition,), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) month = date(2026, 1, 1) years = history(person, month) row = i.evaluate_insured_status( @@ -120,6 +161,9 @@ def test_alien_sspa_requirement_has_explicit_trigger(): date(1980, 2, 2), alien_worker=True, ssn_assignment_date=date(2003, 12, 31), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, ) late = replace(early, ssn_assignment_date=date(2004, 1, 1)) years = history(early, month) @@ -153,7 +197,14 @@ def test_alien_sspa_requirement_has_explicit_trigger(): ], ) def test_raw_earnings_refusals_are_own_layer(year, values, reason): - person = i.Person(date(1914, 2, 2)) + person = i.Person( + date(1914, 2, 2), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) month = date(2028, 1, 1) years = history(person, month) years[year] = i.CoverageYear(i.EarningsProvenance.OBSERVED, **values) @@ -163,7 +214,14 @@ def test_raw_earnings_refusals_are_own_layer(year, values, reason): def test_input_calendar_errors_precede_totalization_refusal(): - person = i.Person(date(1950, 8, 2)) + person = i.Person( + date(1950, 8, 2), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) month = date(1970, 12, 1) years = history(person, month) years[1950] = i.CoverageYear( @@ -187,7 +245,14 @@ def test_input_calendar_errors_precede_totalization_refusal(): @settings(max_examples=15, deadline=None) @given(st.integers(1, 4), st.integers(0, 4)) def test_unknown_birth_and_exit_year_cap_is_sound(quarter, count): - person = i.Person(date(2000, 2, 2)) + person = i.Person( + date(2000, 2, 2), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) month = date(2026, quarter * 3, 1) years = history(person, month, {2024: 4, 2025: 4}) years[2026] = i.CoverageYear(i.EarningsProvenance.UNKNOWN) @@ -216,7 +281,14 @@ def test_unknown_birth_and_exit_year_cap_is_sound(quarter, count): def test_dli_unknown_year_is_a_range_not_an_undocumented_point(): - person = i.Person(date(1980, 2, 2)) + person = i.Person( + date(1980, 2, 2), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) month = date(2026, 12, 1) years = history(person, month, {y: 4 for y in range(2000, 2005)}) years[2005] = i.CoverageYear(i.EarningsProvenance.UNKNOWN) @@ -236,7 +308,15 @@ def test_dli_unknown_year_is_a_range_not_an_undocumented_point(): def test_pre1911_male_dib_fully_requirement_uses_1975_cap_cfr_404_132(): - person = i.Person(date(1900, 2, 2), sex=i.Sex.MALE) + person = i.Person( + date(1900, 2, 2), + sex=i.Sex.MALE, + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) month = date(1974, 12, 1) years = history(person, month, {year: 4 for year in range(1969, 1974)}) result = i.insured_status(person, years, month) @@ -247,7 +327,14 @@ def test_pre1911_male_dib_fully_requirement_uses_1975_cap_cfr_404_132(): def test_requirement_helper_rejects_future_prior_period_and_onset(): - person = i.Person(date(1980, 2, 2)) + person = i.Person( + date(1980, 2, 2), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) month = date(2020, 1, 1) for changed in ( replace(person, disability_onset=date(2021, 1, 1)), @@ -272,6 +359,11 @@ def test_unknown_bounds_with_prior_disability_period(counts): date(2004, 4, 15), date(2006, 9, 15), special_insured=True ), ), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, ) month = date(2012, 12, 1) years = history( diff --git a/tests/test_track_b_insured_status_fix_round_2.py b/tests/test_track_b_insured_status_fix_round_2.py new file mode 100644 index 000000000..9fd5f53f0 --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_2.py @@ -0,0 +1,775 @@ +"""Statutory conformance: round-two invented insured-status regressions. + +No population, behavioral, or forecast claim. Counterexamples were executed +by the independent reviewer against the reviewed head. +""" + +from dataclasses import replace +from datetime import date + +import pytest +from hypothesis import example, given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as i +from tests.test_track_b_insured_status import declared, history + +PROPERTY = settings(max_examples=35, deadline=None) + + +def _person(birth, **values): + declarations = { + "prior_disability_periods_provenance": i.EarningsProvenance.OBSERVED, + "sspa211_applies": False, + "sspa211_provenance": i.EarningsProvenance.OBSERVED, + } + if values.get("disability_onset") is not None: + declarations.update( + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + ) + declarations.update(values) + return i.Person(birth, **declarations) + + +def test_medical_onset_alone_never_freezes_fully_insured_elapsed_years(): + person = _person(date(1980, 2, 2), disability_onset=date(2007, 1, 15)) + month = date(2009, 4, 1) + years = history(person, month, {2008: 4, 2009: 2}) + result = i.insured_status(person, years, month, test=i.InsuredTest.FULLY) + assert result.fully.required == 7 + assert not result.fully.insured + + +def test_continuous_disability_can_first_qualify_after_medical_onset(): + person = _person(date(2000, 2, 2), disability_onset=date(2022, 1, 15)) + month = date(2022, 4, 1) + years = history(person, month, {2021: 4, 2022: 2}) + result = i.insured_status(person, years, month) + assert result.disability.insured + assert result.disability.qc_count_lower == 6 + + +def test_currently_insured_excludes_period_containing_dib_event(): + person = _person( + date(1980, 2, 2), + dib_entitlement_month=date(2004, 7, 1), + prior_disability_periods=( + i.DisabilityPeriod( + date(2004, 1, 1), date(2004, 12, 31), special_insured=True + ), + ), + ) + month = date(2005, 1, 1) + years = history(person, month, {2001: 3, 2002: 3}) + result = i.insured_status( + person, years, month, test=i.InsuredTest.CURRENTLY + ) + assert result.currently.insured + assert result.currently.qc_count_lower == 6 + assert result.currently.window == tuple(range(2000 * 4 + 3, 2004 * 4)) + + +def test_unknown_prerequisite_count_bounds_contain_witness_switch_fillings(): + person = _person( + date(1970, 2, 2), + prior_disability_periods=( + i.DisabilityPeriod(date(2005, 4, 2), date(2015, 9, 30)), + ), + ) + month = date(2020, 12, 1) + counts = {year: 4 for year in (1996, 1997, 1998, 1999, 2000, 2015)} + years = history(person, month, counts) + years[2004] = declared(provenance=i.EarningsProvenance.UNKNOWN) + result = i.insured_status( + person, years, month, test=i.InsuredTest.DISABILITY + ) + concrete = [] + for filling in range(5): + years[2004] = declared(filling) + filled = i.insured_status( + person, years, month, test=i.InsuredTest.DISABILITY + ) + assert filled.disability.insured == result.disability.insured + concrete.append(filled.disability.fully_qc_count_lower) + assert concrete == [24, 23, 24, 25, 26] + assert all( + result.disability.fully_qc_count_lower + <= count + <= result.disability.fully_qc_count_upper + for count in concrete + ) + + +def _quarter(value): + return value.year * 4 + (value.month - 1) // 3 + + +def _quarter_date(quarter): + return date(quarter // 4, 3 * (quarter % 4) + 1, 1) + + +def _plain_quarter_predicate(person, counts, quarter): + """Independent direct-QC predicate: 214(a), 223(c), 404.130-.132. + + Generated births are February 2: ages are attained February 1, so the + age-21 and age-31 quarters have no one-day boundary ambiguity. Annual + QCs are assigned favorably within the candidate quarter and its year. + """ + year = quarter // 4 + fully_required = min(40, max(6, year - (person.birth_date.year + 22))) + total = sum( + min(count, max(0, min(4, quarter - 4 * earnings_year + 1))) + for earnings_year, count in counts.items() + if earnings_year <= year + ) + if total < fully_required: + return False + windows = [(quarter - 39, 20)] + if quarter < (person.birth_date.year + 31) * 4: + first = (person.birth_date.year + 21) * 4 + 1 + elapsed = quarter - first + 1 + if elapsed < 12: + windows.append((quarter - 11, 6)) + elif elapsed > 40: + windows.append((quarter - 39, 20)) + else: + windows.append((first, max(6, elapsed // 2))) + for first, required in windows: + available = sum( + min( + count, + max( + 0, + min(quarter, earnings_year * 4 + 3) + - max(first, earnings_year * 4) + + 1, + ), + ) + for earnings_year, count in counts.items() + ) + if available >= required: + return True + return False + + +@PROPERTY +@given( + birth_year=st.integers(1978, 2000), + onset_age=st.integers(18, 45), + onset_quarter=st.integers(0, 3), + elapsed_quarters=st.integers(0, 12), + annual_counts=st.lists(st.integers(0, 4), min_size=16, max_size=16), +) +def test_continuous_onset_status_and_dli_equal_plain_quarter_scan( + birth_year, onset_age, onset_quarter, elapsed_quarters, annual_counts +): + first = (birth_year + onset_age) * 4 + onset_quarter + last = first + elapsed_quarters + onset = _quarter_date(first).replace(day=15) + month = _quarter_date(last) + person = _person(date(birth_year, 2, 2), disability_onset=onset) + counts = { + year: count + for year, count in zip( + range(last // 4 - 15, last // 4 + 1), annual_counts, strict=True + ) + if year >= birth_year + } + quarters = [ + quarter + for quarter in range(first, last + 1) + if _plain_quarter_predicate(person, counts, quarter) + ] + result = i.insured_status( + person, + history(person, month, counts), + month, + test=i.InsuredTest.DISABILITY, + ) + assert result.disability.insured == bool(quarters) + assert result.disability.insured == ( + result.disability.qc_count_lower >= result.disability.required + and result.disability.fully_qc_count_lower + >= result.disability.fully_required + ) + assert ( + result.dli.lower is not None and _quarter(result.dli.lower) >= first + ) == bool(quarters) + if quarters: + assert result.disability.qualifying_quarter == _quarter_date( + quarters[0] + ) + assert result.disability.window[-1] == quarters[0] + established = replace( + person, current_disability_period_established=True + ) + frozen = i.insured_status( + established, + history(established, month, counts), + month, + test=i.InsuredTest.DISABILITY, + ) + expected_start = ( + onset if quarters[0] == first else _quarter_date(quarters[0]) + ) + assert frozen.current_disability_period_start == expected_start + # CFR404.315(a): a waiting month is both disabled and insured. + # No such month can precede the derived period's first insured year. + assert all( + not _plain_quarter_predicate(person, counts, quarter) + for quarter in range(first, quarters[0]) + ) + assert expected_start.year == _quarter_date(quarters[0]).year + + +@PROPERTY +@given( + shift=st.integers(0, 4), + late_count=st.integers(0, 4), + filling=st.integers(0, 4), +) +def test_unknown_recent_and_fully_counts_contain_concrete_period_fillings( + shift, late_count, filling +): + """Include the reviewer's treatment switch: 24,23,24,25,26 QCs.""" + person = _person( + date(1970 + shift, 2, 2), + prior_disability_periods=( + i.DisabilityPeriod( + date(2005 + shift, 4, 2), date(2015 + shift, 9, 30) + ), + ), + ) + month = date(2020 + shift, 12, 1) + counts = {year + shift: 4 for year in (1996, 1997, 1998, 1999, 2000, 2015)} + counts[2019 + shift] = late_count + years = history(person, month, counts) + years[2004 + shift] = declared(provenance=i.EarningsProvenance.UNKNOWN) + try: + bounded = i.insured_status( + person, years, month, test=i.InsuredTest.DISABILITY + ) + except i.InsuredConfigurationUnsupported as error: + assert error.reason is i.InsuredUnsupportedReason.UNKNOWN_EARNINGS + return + years[2004 + shift] = declared(filling) + concrete = i.insured_status( + person, years, month, test=i.InsuredTest.DISABILITY + ) + assert bounded.disability.insured == concrete.disability.insured + assert ( + bounded.disability.qc_count_lower + <= concrete.disability.qc_count_lower + <= bounded.disability.qc_count_upper + ) + assert ( + bounded.disability.fully_qc_count_lower + <= concrete.disability.fully_qc_count_lower + <= bounded.disability.fully_qc_count_upper + ) + + +@PROPERTY +@example( + start_year=2005, + end_year=2015, + recent=[4, 4, 4, 4, 4], + kind=i.InsuredTest.DISABILITY, + current_unknown=True, + early_current=False, + established_current=False, +) +@example( + start_year=2005, + end_year=2015, + recent=[0, 0, 0, 0, 0], + kind=i.InsuredTest.DISABILITY, + current_unknown=True, + early_current=True, + established_current=False, +) +@example( + start_year=2005, + end_year=2015, + recent=[0, 0, 0, 0, 0], + kind=i.InsuredTest.DISABILITY, + current_unknown=True, + early_current=False, + established_current=False, +) +@example( + start_year=2005, + end_year=2015, + recent=[0, 0, 0, 0, 0], + kind=i.InsuredTest.DISABILITY, + current_unknown=True, + early_current=True, + established_current=True, +) +@given( + established_current=st.booleans(), + early_current=st.booleans(), + current_unknown=st.booleans(), + start_year=st.integers(2005, 2008), + end_year=st.integers(2010, 2015), + recent=st.lists(st.integers(0, 4), min_size=5, max_size=5), + kind=st.sampled_from( + [ + i.InsuredTest.FULLY, + i.InsuredTest.CURRENTLY, + i.InsuredTest.DISABILITY, + ] + ), +) +def test_unknown_period_status_and_dli_bounds_contain_concrete_fillings( + start_year, + end_year, + recent, + kind, + current_unknown, + early_current, + established_current, +): + """The declared prior period was insured at its start for every draw.""" + month = date(2020, 12, 1) + onset_year = 2004 if early_current else 2016 + if early_current: + start_year = 2000 + (start_year - 2005) // 2 + end_year = 2003 + unknown = _person( + date(1970, 2, 2), + prior_disability_periods_provenance=i.EarningsProvenance.UNKNOWN, + **( + { + "disability_onset": date(onset_year, 1, 15), + "current_disability_period_established": ( + True if early_current and established_current else None + ), + "current_disability_period_provenance": ( + i.EarningsProvenance.OBSERVED + if early_current and established_current + else i.EarningsProvenance.UNKNOWN + ), + } + if current_unknown + else {} + ), + ) + first_earnings_year = 1990 if early_current else 1995 + counts = { + year: 4 + for year in range(first_earnings_year, first_earnings_year + 10) + } + counts.update(zip(range(2016, 2021), recent, strict=True)) + years = history(unknown, month, counts) + try: + bounded = i.insured_status(unknown, years, month, test=kind) + except i.InsuredConfigurationUnsupported as error: + if ( + early_current + and current_unknown + and established_current + and kind in (i.InsuredTest.FULLY, i.InsuredTest.DISABILITY) + ): + pytest.fail("Disregarding all periods already proves insurance") + assert error.reason in ( + i.InsuredUnsupportedReason.UNKNOWN_PERIODS, + i.InsuredUnsupportedReason.UNKNOWN_CURRENT_PERIOD, + ) + return + assert bounded.decided_despite_unknowns + for periods in ( + (), + (i.DisabilityPeriod(date(start_year, 4, 2), date(end_year, 9, 30)),), + ): + known = replace( + unknown, + prior_disability_periods=periods, + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + **( + { + "current_disability_period_established": False, + "current_disability_period_provenance": i.EarningsProvenance.OBSERVED, + } + if current_unknown + else {} + ), + ) + completions = ( + [] if unknown.current_disability_period_established else [known] + ) + if current_unknown: + credits = { + year: i._credits(year, row, False) + for year, row in years.items() + } + if any( + i._witness( + known, + credits, + _quarter_date(quarter), + None, + i.InsuredTest.DISABILITY, + )[0] + for quarter in range( + _quarter(known.disability_onset), _quarter(month) + 1 + ) + ): + completions.append( + replace(known, current_disability_period_established=True) + ) + for completed in completions: + concrete = i.insured_status(completed, years, month, test=kind) + name = kind.value + assert ( + getattr(bounded, name).insured + == getattr(concrete, name).insured + ) + if concrete.dli is not None: + assert bounded.dli is not None + if concrete.dli.lower is not None: + assert bounded.dli.lower is None or ( + bounded.dli.lower <= concrete.dli.lower + ) + assert bounded.dli.upper is not None + assert concrete.dli.upper <= bounded.dli.upper + + +def test_sam_white_can_become_insured_later_poms_140_example_2(): + """Published birth/onset; the missing later earnings are invented.""" + person = _person(date(1961, 8, 20), disability_onset=date(1984, 4, 12)) + onset_month = date(1984, 4, 1) + later_month = date(1984, 7, 1) + counts = {1983: 3, 1984: 3} + onset = i.insured_status( + person, + history(person, onset_month, counts), + onset_month, + test=i.InsuredTest.DISABILITY, + ) + later = i.insured_status( + person, + history(person, later_month, counts), + later_month, + test=i.InsuredTest.DISABILITY, + ) + assert not onset.disability.insured + assert onset.disability.qc_count_lower == 5 + assert later.disability.insured + assert later.disability.qc_count_lower == 6 + assert later.disability.qualifying_quarter == later_month + assert later.disability.window[-1] == 1984 * 4 + 2 + + +def test_missing_current_period_declaration_is_input_error_with_onset(): + with pytest.raises(i.InvalidFamilyInput): + person = i.Person( + date(1980, 2, 2), + disability_onset=date(2007, 1, 15), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) + month = date(2009, 4, 1) + i.insured_status( + person, history(person, month, {2008: 4, 2009: 2}), month + ) + + +def test_explicit_unknown_current_period_can_decide_status_without_a_freeze(): + person = _person( + date(1980, 2, 2), + disability_onset=date(2020, 1, 15), + current_disability_period_established=None, + current_disability_period_provenance=i.EarningsProvenance.UNKNOWN, + ) + month = date(2026, 1, 1) + years = history(person, month, {year: 4 for year in range(2010, 2020)}) + result = i.insured_status(person, years, month, test=i.InsuredTest.FULLY) + assert result.fully.insured + assert result.decided_despite_unknowns + + +def test_unknown_sspa_applicability_does_not_block_qc_only_uninsured_result(): + person = _person( + date(1980, 2, 2), + sspa211_applies=None, + sspa211_provenance=i.EarningsProvenance.UNKNOWN, + ) + month = date(2026, 1, 1) + result = i.insured_status(person, history(person, month), month) + assert not result.fully.insured + assert not result.currently.insured + assert not result.disability.insured + assert result.decided_despite_unknowns + + # Current status can be false while the QC-only historical DLI is positive. + old_years = history(person, month, {year: 4 for year in range(2000, 2005)}) + historical = i.insured_status(person, old_years, month) + exempt = i.insured_status( + replace( + person, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ), + old_years, + month, + ) + assert not historical.fully.insured + assert not historical.currently.insured + assert not historical.disability.insured + assert historical.decided_despite_unknowns + assert exempt.dli.lower == exempt.dli.upper == date(2009, 12, 31) + assert historical.dli.lower is None + assert historical.dli.upper == exempt.dli.upper + + +def test_unknown_sspa_applicability_refuses_when_qcs_would_insure(): + person = _person( + date(1980, 2, 2), + sspa211_applies=None, + sspa211_provenance=i.EarningsProvenance.UNKNOWN, + ) + month = date(2026, 1, 1) + years = history(person, month, {year: 4 for year in range(2010, 2020)}) + with pytest.raises(i.InsuredConfigurationUnsupported) as error: + i.insured_status(person, years, month, test=i.InsuredTest.FULLY) + assert error.value.reason.value == "sspa211_applicability_unknown" + + +def test_never_assigned_ssn_retains_sspa211_additional_requirement(): + person = _person( + date(1980, 2, 2), + alien_worker=True, + ssn_never_assigned=True, + sspa211_applies=None, + sspa211_provenance=i.EarningsProvenance.UNKNOWN, + ) + month = date(2026, 1, 1) + years = history(person, month, {year: 4 for year in range(2010, 2020)}) + with pytest.raises(i.InsuredConfigurationUnsupported) as error: + i.insured_status(person, years, month, test=i.InsuredTest.FULLY) + assert error.value.reason is i.InsuredUnsupportedReason.ALIEN_WORKER + + +@PROPERTY +@given( + provenance=st.sampled_from( + [ + i.EarningsProvenance.OBSERVED, + i.EarningsProvenance.CONVENTION_FILLED, + ] + ), + count=st.integers(0, 4), +) +def test_declared_fact_provenance_preserves_computed_status(provenance, count): + month = date(2022, 4, 1) + person = _person(date(2000, 2, 2), disability_onset=date(2022, 1, 15)) + years = history(person, month, {2021: 4, 2022: count}) + observed = i.insured_status(person, years, month) + convention_id = ( + "invented-round-two-facts" + if provenance is i.EarningsProvenance.CONVENTION_FILLED + else None + ) + alternate = replace( + person, + prior_disability_periods_provenance=provenance, + prior_disability_periods_convention_id=convention_id, + current_disability_period_provenance=provenance, + current_disability_period_convention_id=convention_id, + sspa211_provenance=provenance, + sspa211_convention_id=convention_id, + ) + result = i.insured_status(alternate, years, month) + assert result.fully == observed.fully + assert result.currently == observed.currently + assert result.disability == observed.disability + assert result.dli == observed.dli + + +@pytest.mark.parametrize( + "counts,expected_start", + [ + ({2020: 2, 2021: 4}, date(2022, 1, 15)), + ({2021: 4, 2022: 2}, date(2022, 4, 1)), + ], + ids=["insured-onset-day", "first-later-insured-quarter"], +) +def test_established_current_period_starts_only_when_disabled_and_insured( + counts, expected_start +): + person = _person( + date(2000, 2, 2), + disability_onset=date(2022, 1, 15), + current_disability_period_established=True, + ) + month = date(2022, 4, 1) + result = i.insured_status(person, history(person, month, counts), month) + assert result.current_disability_period_start == expected_start + assert result.disability.insured + assert result.disability.qualifying_quarter == expected_start.replace( + month=3 * ((expected_start.month - 1) // 3) + 1, day=1 + ) + + +def test_unknown_current_period_refuses_when_establishment_changes_full_status(): + person = _person( + date(1980, 2, 2), + disability_onset=date(2000, 1, 15), + current_disability_period_established=None, + current_disability_period_provenance=i.EarningsProvenance.UNKNOWN, + ) + month = date(2009, 4, 1) + years = history(person, month, {1999: 4, 2000: 2}) + with pytest.raises(i.InsuredConfigurationUnsupported) as error: + i.insured_status(person, years, month, test=i.InsuredTest.FULLY) + assert ( + error.value.reason is i.InsuredUnsupportedReason.UNKNOWN_CURRENT_PERIOD + ) + unfrozen = i.insured_status( + replace( + person, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + ), + years, + month, + test=i.InsuredTest.ALL, + ) + frozen = i.insured_status( + replace( + person, + current_disability_period_established=True, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + ), + years, + month, + test=i.InsuredTest.FULLY, + ) + assert not unfrozen.fully.insured + assert unfrozen.fully.required == 7 + assert unfrozen.disability.insured + assert unfrozen.disability.qualifying_quarter == date(2000, 4, 1) + assert ( + unfrozen.disability.fully_qc_count_lower + >= unfrozen.disability.fully_required + ) + assert frozen.fully.insured + assert frozen.fully.required == 6 + assert frozen.current_disability_period_start == date(2000, 4, 1) + + +@PROPERTY +@example(counts=(0, 0), kind=i.InsuredTest.DISABILITY, old_history=True) +@given( + old_history=st.booleans(), + counts=st.tuples(st.integers(0, 4), st.integers(0, 4)).filter( + lambda values: sum(values) < 6 + ), + kind=st.sampled_from( + [ + i.InsuredTest.FULLY, + i.InsuredTest.CURRENTLY, + i.InsuredTest.DISABILITY, + ] + ), +) +def test_unknown_sspa_applicability_preserves_qc_impossibility( + counts, kind, old_history +): + month = date(2026, 1, 1) + person = _person( + date(1980, 2, 2), + sspa211_applies=None, + sspa211_provenance=i.EarningsProvenance.UNKNOWN, + ) + annual_counts = {2025: counts[0], 2026: counts[1]} + if old_history: + annual_counts.update({year: 4 for year in range(2000, 2005)}) + years = history(person, month, annual_counts) + exempt = i.insured_status( + replace( + person, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ), + years, + month, + test=kind, + ) + try: + uncertain = i.insured_status(person, years, month, test=kind) + except i.InsuredConfigurationUnsupported as error: + assert error.reason is i.InsuredUnsupportedReason.UNKNOWN_SSPA211 + assert getattr(exempt, kind.value).insured + return + assert not getattr(uncertain, kind.value).insured + assert ( + getattr(uncertain, kind.value).insured + == getattr(exempt, kind.value).insured + ) + assert uncertain.decided_despite_unknowns + + if exempt.dli is not None: + assert uncertain.dli is not None + assert uncertain.dli.lower is None + assert uncertain.dli.upper == exempt.dli.upper + + +@PROPERTY +@given( + shift=st.integers(0, 3), + onset_offset=st.integers(0, 11), + recent=st.lists(st.integers(0, 4), min_size=5, max_size=5), +) +def test_continuous_onset_with_prior_period_matches_plain_predicate_scan( + shift, onset_offset, recent +): + """Shared per-quarter predicate checks the scan with prior treatments.""" + first = (2016 + shift) * 4 + onset_offset + month = date(2020 + shift, 12, 1) + person = _person( + date(1970 + shift, 2, 2), + disability_onset=_quarter_date(first).replace(day=15), + prior_disability_periods=( + i.DisabilityPeriod( + date(2005 + shift, 4, 2), date(2015 + shift, 9, 30) + ), + ), + ) + counts = {year + shift: 4 for year in range(1995, 2005)} + counts.update(zip(range(2016 + shift, 2021 + shift), recent, strict=True)) + years = history(person, month, counts) + credits = { + year: i._credits(year, row, False) for year, row in years.items() + } + quarters = [ + quarter + for quarter in range(first, _quarter(month) + 1) + if i._witness( + person, + credits, + _quarter_date(quarter), + None, + i.InsuredTest.DISABILITY, + )[0] + ] + result = i.insured_status( + person, years, month, test=i.InsuredTest.DISABILITY + ) + assert result.disability.insured == bool(quarters) + assert result.disability.insured == ( + result.disability.qc_count_lower >= result.disability.required + and result.disability.fully_qc_count_lower + >= result.disability.fully_required + ) + assert ( + result.dli.lower is not None and _quarter(result.dli.lower) >= first + ) == bool(quarters) + if quarters: + assert result.disability.qualifying_quarter == _quarter_date( + quarters[0] + ) + assert result.disability.window[-1] == quarters[0] diff --git a/tests/test_track_b_insured_status_mutations.py b/tests/test_track_b_insured_status_mutations.py new file mode 100644 index 000000000..aececbadc --- /dev/null +++ b/tests/test_track_b_insured_status_mutations.py @@ -0,0 +1,27 @@ +"""Statutory conformance: review mutation evidence stays with design notes. + +Invented and captured statutory cases only; no population or forecast claim. +""" + +import json +from pathlib import Path + + +def test_mutation_report_is_retained_with_its_design_note(): + root = Path(__file__).resolve().parents[1] + name = "track_b_insured_status_mutations.json" + report = root / "docs" / "design" / name + assert report.is_file() + assert ( + name + in (root / "docs" / "design" / "track_b_insured_status.md").read_text() + ) + evidence = json.loads(report.read_text()) + assert evidence["verification_class"] == "statutory_conformance" + assert not ( + root + / "tests" + / "data" + / "track_b" + / "insured_status_mutation_checks.json" + ).exists() diff --git a/tests/test_track_b_insured_status_period_declarations.py b/tests/test_track_b_insured_status_period_declarations.py new file mode 100644 index 000000000..2569222d0 --- /dev/null +++ b/tests/test_track_b_insured_status_period_declarations.py @@ -0,0 +1,177 @@ +"""Statutory conformance: administrative period facts and unknown histories. + +Invented declarations only; no population, behavioral, or forecast claim. +""" + +from dataclasses import replace +from datetime import date + +import pytest + +from populace_dynamics.track_b import insured_status as i +from populace_dynamics.track_b.gross_benefits import InvalidFamilyInput +from tests.test_track_b_insured_status import history + + +def test_established_current_period_with_unknown_prior_periods_uses_bounds(): + person = i.Person( + date(2000, 2, 2), + disability_onset=date(2022, 1, 15), + prior_disability_periods_provenance=i.EarningsProvenance.UNKNOWN, + current_disability_period_established=True, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) + month = date(2022, 4, 1) + years = history(person, month, {2021: 4, 2022: 2}) + result = i.insured_status(person, years, month, test=i.InsuredTest.FULLY) + assert result.fully.insured + assert result.current_disability_period_start is None + assert result.unknown_facts == ( + "prior_disability_periods", + "current_disability_period_start", + ) + assert result.decided_despite_unknowns + disability = i.insured_status( + person, years, month, test=i.InsuredTest.DISABILITY + ) + assert disability.disability.insured + assert disability.current_disability_period_start is None + assert disability.unknown_facts == result.unknown_facts + assert disability.decided_despite_unknowns + assert disability.dli.lower == disability.dli.upper == date(2022, 6, 30) + assert disability.dli.right_censored + + concrete_person = replace( + person, + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + ) + concrete = i.insured_status(concrete_person, years, month) + assert concrete.fully.insured == result.fully.insured + assert concrete.disability.insured == disability.disability.insured + assert concrete.current_disability_period_start == date(2022, 4, 1) + assert disability.dli.lower <= concrete.dli.lower <= disability.dli.upper + + # No established period can overcome the universal six-QC minimum. + with pytest.raises(InvalidFamilyInput): + i.insured_status( + person, + history(person, month), + month, + test=i.InsuredTest.FULLY, + ) + + for foreign_credits, conditions in ( + (("invented-foreign-credit",), frozenset()), + ((), frozenset({i.CoverageCondition.RAILROAD_CREDITS})), + ): + invalid_person = replace(person, conditions=conditions) + with pytest.raises(InvalidFamilyInput): + i.insured_status( + invalid_person, + history(invalid_person, month), + month, + test=i.InsuredTest.FULLY, + totalization_credits=foreign_credits, + ) + + +def test_unknown_earnings_deciding_established_current_start_refuse_by_name(): + person = i.Person( + date(2000, 2, 2), + disability_onset=date(2022, 1, 15), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=True, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) + month = date(2022, 4, 1) + years = history(person, month, {2022: 2}) + years[2021] = i.CoverageYear(i.EarningsProvenance.UNKNOWN) + with pytest.raises(i.InsuredConfigurationUnsupported) as error: + i.insured_status(person, years, month, test=i.InsuredTest.FULLY) + assert error.value.reason is i.InsuredUnsupportedReason.UNKNOWN_EARNINGS + + +def test_requirement_calendar_error_precedes_unknown_period_refusal(): + person = i.Person( + date(2000, 2, 2), + prior_disability_periods_provenance=i.EarningsProvenance.UNKNOWN, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) + with pytest.raises(InvalidFamilyInput): + i.fully_insured_requirement(person, date(1999, 1, 1)) + + +def test_unknown_period_dli_capped_before_query_is_not_right_censored(): + person = i.Person( + date(1950, 2, 2), + prior_disability_periods_provenance=i.EarningsProvenance.UNKNOWN, + current_disability_period_established=False, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) + month = date(2026, 1, 1) + counts = {year: 4 for year in (*range(2000, 2010), *range(2017, 2027))} + years = history(person, month, counts) + result = i.insured_status( + person, years, month, test=i.InsuredTest.DISABILITY + ) + assert result.disability.insured + assert result.dli.upper < month + assert not result.dli.right_censored + + +def test_established_current_period_refuses_unobserved_future_dli_only(): + person = i.Person( + date(2000, 2, 2), + disability_onset=date(2022, 1, 15), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=True, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) + month = date(2022, 10, 1) + years = history(person, month, {2021: 4, 2022: 2}) + with pytest.raises(i.InsuredConfigurationUnsupported) as error: + i.insured_status( + person, + years, + month, + coverage_end_month=month, + test=i.InsuredTest.DISABILITY, + ) + assert error.value.reason is i.InsuredUnsupportedReason.CURRENT_PERIOD_DLI + fully = i.insured_status( + person, + years, + month, + coverage_end_month=month, + test=i.InsuredTest.FULLY, + ) + assert fully.fully.insured + assert fully.dli is None + + +def test_requirement_current_period_establishment_requires_coverage_history(): + person = i.Person( + date(2000, 2, 2), + disability_onset=date(2022, 1, 15), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_established=True, + current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + sspa211_applies=False, + sspa211_provenance=i.EarningsProvenance.OBSERVED, + ) + with pytest.raises(i.InsuredConfigurationUnsupported) as error: + i.fully_insured_requirement(person, date(2022, 10, 1)) + assert ( + error.value.reason is i.InsuredUnsupportedReason.CURRENT_PERIOD_HISTORY + ) diff --git a/tests/test_track_b_insured_status_sources.py b/tests/test_track_b_insured_status_sources.py index ef7c570ba..249f3ef4d 100644 --- a/tests/test_track_b_insured_status_sources.py +++ b/tests/test_track_b_insured_status_sources.py @@ -62,6 +62,14 @@ def source_text(source_id): "Section 211 of the SSPA applies to an alien worker whose Social " "Security Number (SSN) was first assigned on or after January 1, " "2004.", + "An alien worker whose SSN was assigned before January 1, 2004 is " + "exempt from the requirements of Section 211 of the Social Security " + "Protection Act, even if the SSN was not work authorized.", + "Section 211 of the SSPA applies if the alien worker's own SSN was " + "assigned on or after 1/1/2004 or if they have not yet been assigned " + "an SSN based on their true identity.", + "Alien worker does not have an SSN, but is currently authorized to " + "work in the U.S.; or", ], "poms_rs_00301_105": [ "A NH needs at least 6 QCs and no more than 40 QCs to meet fully " @@ -228,6 +236,39 @@ def source_text(source_id): "You reach a particular age on the day before your birthday.", "You are fully insured as of the first day of the calendar " "quarter in which you acquire the last needed QC", + "we do not count as an elapsed year any year which is wholly or " + "partly in a period of disability we established for you.", + "You have at least 20 QCs in the 40-quarter period (see paragraph " + "(f) of this section) ending with that quarter.", + "You have QCs in at least one-half of the quarters during the " + "period ending with that quarter and beginning with the quarter " + "after the quarter you became age 21;", + "However, we will count all the quarters in the prior period of " + "disability established for you if by doing so you would be " + "entitled to benefits or the amount of the benefit would be larger.", + ], + "ecfr_20cfr404_315": [ + "The 5-month waiting period begins with a month in which you were " + "both insured for disability and disabled.", + "You apply;", + ], + "ecfr_20cfr404_320": [ + "If benefits payable on your earnings record would be denied or " + "reduced because of a period of disability, the period of " + "disability will not be taken into consideration.", + "You file an application while disabled, or no later than 12 " + "months after the month in which your period of disability ended.", + "At least 5 consecutive months go by from the month in which " + "your period of disability begins and before the month in which " + "it would end.", + ], + "ecfr_20cfr404_321": [ + "Your period of disability begins on the day your disability " + "begins if you are insured for disability on that day.", + "If you are not insured for disability on that day, your period " + "of disability will begin on the first day of the first calendar " + "quarter after your disability began in which you become insured " + "for disability.", ], "lii_usc_42_413": [ "with such product, if not a multiple of $10, being rounded " @@ -271,7 +312,7 @@ def test_manifest_pins_every_capture(): document = manifest() assert document["schema_version"] == 1 sources = document["sources"] - assert len(sources) == 45 + assert len(sources) == 48 assert len({source["id"] for source in sources}) == len(sources) for source in sources: data = (SOURCES / source["file"]).read_bytes() @@ -393,7 +434,10 @@ def test_poms_102_never_assigned_ssn_is_a_named_refusal(example_id, quote): # zero history only supplies structurally valid input to the explicitly # unsupported SSPA adjudication; it is not a claim about their earnings. person = i.Person( - date(1960, 1, 2), alien_worker=True, ssn_never_assigned=True + date(1960, 1, 2), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + alien_worker=True, + ssn_never_assigned=True, ) month = date(2026, 1, 1) years = { @@ -426,6 +470,7 @@ def test_never_assigned_ssn_cannot_also_have_an_assignment_date(): with pytest.raises(InvalidFamilyInput): i.Person( date(1960, 1, 2), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, alien_worker=True, ssn_never_assigned=True, ssn_assignment_date=date(2004, 1, 2), From 3fd1d2253dff26fa12e628e1926390b518a294f6 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sun, 25 Oct 2026 05:55:48 -0400 Subject: [PATCH 07/46] Recount test tiers after insured-status fix round 2 Co-Authored-By: Claude Opus 5.5 --- tests/README-tiers.md | 4 ++-- tests/tier_counts.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/README-tiers.md b/tests/README-tiers.md index 204ce92a6..2087291b3 100644 --- a/tests/README-tiers.md +++ b/tests/README-tiers.md @@ -39,9 +39,9 @@ pytest --collect-only -q -m oracle_policyengine | tail -1 | Tier | Tests at HEAD | |---|---:| -| `unit` | 19,575 | +| `unit` | 19,629 | | `artifact` | 4,271 | | `integration_psid` | 1,450 | | `reproduction_legacy` | 520 | | `oracle_policyengine` | 308 | -| **Total** | **26,124** | +| **Total** | **26,178** | diff --git a/tests/tier_counts.json b/tests/tier_counts.json index 560d51513..f5aac19de 100644 --- a/tests/tier_counts.json +++ b/tests/tier_counts.json @@ -1,7 +1,7 @@ { "schema_version": 1, "counts": { - "unit": 19575, + "unit": 19629, "artifact": 4271, "integration_psid": 1450, "reproduction_legacy": 520, From 7a27f502dcf22eada470ac52d0ee6873d232add9 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sat, 31 Oct 2026 07:52:31 -0400 Subject: [PATCH 08/46] Bound insured status by period ends, FRA and pre-1951 credits (#562 round 3) The round-2 review of #562 found five medium issues. This commit fixes them under 42 U.S.C. 413(c), 416(i)(2) and 416(l) and 20 CFR 404.320-.321: - An ongoing period stays ongoing. The query no longer ends it, and an unknown end that decides a status refuses by name. - Full retirement age bounds every established period's start and end. - Supplied 1937-1950 wages now trigger the Act 213(c) alternative automatically, and the refused table says which specialist refusals the rule can observe from its inputs. - A declaration that every concrete filling makes invalid raises InvalidFamilyInput and creates no denominator row. - The design note gives Sam's fully insured prerequisite as seven. Subfleet job 20261025-084543-trackb-fix-insured-3 (gpt-6.1-sol) wrote this work and left it uncommitted; salvage ref 274d2d09 preserved its tree. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 150 +++++- .../track_b_insured_status_mutations.json | 325 +++++++++++- .../track_b/insured_status.py | 349 +++++++++++- tests/README-tiers.md | 4 +- .../data/track_b/insured_status_examples.yaml | 2 +- tests/test_track_b_insured_status.py | 8 + ...k_b_insured_status_fix_round_3_coverage.py | 372 +++++++++++++ ...ck_b_insured_status_fix_round_3_periods.py | 498 ++++++++++++++++++ ...b_insured_status_fix_round_3_validation.py | 207 ++++++++ tests/test_track_b_insured_status_sources.py | 68 +++ tests/tier_counts.json | 2 +- 11 files changed, 1951 insertions(+), 34 deletions(-) create mode 100644 tests/test_track_b_insured_status_fix_round_3_coverage.py create mode 100644 tests/test_track_b_insured_status_fix_round_3_periods.py create mode 100644 tests/test_track_b_insured_status_fix_round_3_validation.py diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index e4cb577c5..407d65452 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -123,6 +123,48 @@ fact itself remains known. If the disregard treatment already qualifies at medical onset, onset is the certain start. Disregard is a permitted statutory treatment, not an assertion that a known period never existed. +Round 3 additionally proves when UNKNOWN prior history can only be empty +for establishment validation. The earliest nonempty period would need an +insured starting quarter without any earlier period (404.320(b)(2), +404.321(a)), on or after birth, before FRA, with time for five months before +its ending month (404.320(b)(4)), and an end before the current onset. +The scan uses the highest feasible QCs for every unknown year and a +permissive partial-month duration bound. If no quarter survives, validate +the current declaration against empty prior history at those highest QCs. +If even that world has no insured current start, raise `InvalidFamilyInput` +before any coverage refusal. An evaluator then creates no denominator row. +If a quarter survives, feasibility is unproved and a named refusal remains +possible. This is a sufficient invalidity proof, not a complete history +solver. For valid declarations the caller's UNKNOWN provenance, uncertain +start disclosure, and universal count envelope remain conservative; the +validation collapse does not invent an observed history. + +An observation month never establishes a period's ending month. The +statutory end is the earlier of a declared administrative end and the last +day of the month before FRA (416(i)(2)(D); 404.321(c)); death also bounds the +declared lifetime. `current_disability_period_end` optionally supplies that +administrative ending date, on the last day of a month, with +`current_disability_period_end_provenance` and, for a convention, +`current_disability_period_end_convention_id`. An omitted end stays unknown. +These three optional fields append after the original twenty `Person` +fields, preserving the existing positional facts as well as keyword calls. +For an ongoing period the rule compares an end in the observation month +with continuation through the statutory FRA limit. The observation quarter +may be credited as the last quarter in the former world but interior in +the latter (404.146(d); 404.120(b)). When a requested status differs, the +call refuses with `ongoing_disability_period_end_decides_status`; when it +agrees, counts contain both worlds and the unknown ending is disclosed. +At or beyond FRA the calendar supplies the actual cap rather than an +unknown ending. Established starts at or after FRA are invalid even if +prior history is UNKNOWN, and every supplied prior period is capped at +the month before FRA. The standalone requirement helper shares these +limits. A start in the FRA attainment month is also invalid because its +mandatory end would precede its start, including a first-day birthday +whose FRA is attained at the end of the previous month. The FRA date and +quarter share the 416(l)(1)–(3) cohort schedule; +January 1 birthdays use the preceding attainment year, and the date itself +is the day before the birthday at the statutory age. + The disability test scans the onset quarter through the query quarter. Each candidate's 20/40 or special window ends in that candidate quarter, and its fully insured prerequisite ends elapsed years before the @@ -209,7 +251,9 @@ QCs before period exclusions. Multiple historical event witnesses can also switch as unknown credits rise, so they use the same envelope. This universal envelope contains every concrete recent and fully-prerequisite count. Complete observed inputs -retain exact counts. No narrower selected-witness bound is claimed. +with known period ends retain exact counts. An ongoing ending can widen +counts even when every earnings year is observed. No narrower +selected-witness bound is claimed. If either bound differs on a requested Boolean status, the call raises the sealed `unknown_earnings_years_decide_status` refusal. If both agree, the @@ -312,6 +356,7 @@ a subclass of the shared `FamilyConfigurationUnsupported`. | Unknown-year bounds decide a requested status differently | `unknown_earnings_years_decide_status` | | Unknown prior periods may change a requested status | `unknown_prior_disability_periods_decide_status` | | Unknown current establishment may change a requested status | `unknown_current_disability_period_decides_status` | +| Ongoing current period's observation-quarter ending versus continuation changes a requested status | `ongoing_disability_period_end_decides_status` | | Unknown section 214(c) applicability may change a requested status | `sspa211_applicability_unknown` | | Standalone requirement helper needs coverage history to derive a declared current period start | `current_disability_period_requires_history` | | Ongoing established current period, known prior-period history, and a frozen-exit DLI horizon beyond query | `ongoing_disability_period_dli_horizon_unsupported` | @@ -323,7 +368,7 @@ a subclass of the shared `FamilyConfigurationUnsupported`. | Medicare-qualified government employment | `medicare_government_employment_unsupported` | | Earned-basis wages or pre1956 alternate disability | `earned_basis_unsupported`, `disability_before_1956_unsupported` | | Fiscal or short taxable-year public declaration | `fiscal_taxable_year_unsupported`, `short_taxable_year_unsupported` | -| Simplified pre1951 aggregate computation | `simplified_pre1951_unsupported` | +| Supplied pre1951 wages, or UNKNOWN pre1951 years, could make a failed fully insured test pass under the simplified method; also an explicit specialist declaration | `simplified_pre1951_unsupported` | | Positive raw1937 earnings needing half-year/age65 rules | `1937_earnings_allocation_unsupported` | | Separate pre1955 agricultural annual wages | `pre1955_agricultural_allocation_unsupported` | | Pre1951 self-employment income | `pre1951_self_employment_unsupported` | @@ -331,6 +376,38 @@ a subclass of the shared `FamilyConfigurationUnsupported`. | Query before 1968; blind query before 1973; subsequent-special query before May 1983 | `entitlement_before_1968_unsupported`, `blindness_before_1973_unsupported`, `subsequent_special_before_1983_unsupported` | | More than 4,096 disability-boundary combinations | `disability_boundary_assignments_unsupported` | +The round-3 observable-trigger audit covers every `CoverageCondition`. +An explicit condition continues to refuse independently of its ordinary +status result. Automatic detection additionally applies where the ordinary +declarations reveal a potentially decisive specialist route: + +The pre1951 bound compares the deemed-credit aggregate with the smallest +fully insured requirement across permitted freeze treatments, including +the derived current period (213(c); 404.110(c)–(d); 404.130(f)). The selected +ordinary witness can have more QCs and a higher requirement, so its +requirement alone is insufficient. UNKNOWN prior or current establishment +uses the universal six-QC requirement as a conservative possibility bound. +Post1950 upper credits are counted without period exclusions for this +refusal check; this may refuse extra cases but cannot silently deny a +potentially favorable specialist path. It does not compute deemed-credit +allocation or adjudicate application facts. + +| Condition | Observable trigger or absent fact | +| --- | --- | +| `SIMPLIFIED_PRE1951` | Raw 1937–1950 quarterly wages provide an aggregate divided by $400; post1950 upper QCs and the fully insured prerequisite bound whether it could decide status (213(c); 404.110(d); RS .315). UNKNOWN pre1951 years can supply unbounded raw wages and therefore also trigger the refusal. Direct `qc_quarters` declare credited quarters rather than raw wages. The simplified method does not apply to a disability claim. Filing, retroactivity, and section 227 facts remain unmodeled. | +| `DISABILITY_BEFORE_1956` | Medical onset and QCs reveal a possible RS .480 alternative: at least 20 total QCs and every quarter from 1951Q1 through the quarter before a qualifying 1952Q3–1955Q4 candidate quarter at or after onset, with at least six such quarters. Refuse automatically when this could change a failed disability predicate. Application conditions remain unmodeled. | +| `DEEMED_FULLY_INSURED` | Wages and dates do not identify covered nonprofit employment or veteran status; retain the explicit flag (404.111–.112; RS .106/.107/.470). | +| `TRANSITIONAL_INSURED` | Cohort dates alone do not identify the necessary historical benefit/application facts; retain the explicit flag (RS .101's transitional-benefit referrals). | +| `RAILROAD_CREDITS`, `MILITARY_CREDITS` | Ordinary covered earnings do not identify railroad or military service and additional credits; retain explicit flags (RS .350; RS .120/.470). | +| `MEDICARE_GOVERNMENT_EMPLOYMENT` | Covered amounts do not identify government employment or Medicare-only coverage; retain the explicit flag (RS .160/.161). | +| `EARNED_BASIS` | Paid calendar-quarter amounts do not disclose when those wages were earned; retain the explicit flag (213(a); RS .475). | +| `FISCAL_TAXABLE_YEAR`, `SHORT_TAXABLE_YEAR` | Calendar-year self-employment totals do not disclose the taxpayer's fiscal or short taxable-year dates; retain explicit flags (404.142/.144; RS .220/.340/.345). | + +Raw1937 earnings, separate pre1955 agriculture, and pre1951 self-employment +already have automatic refusals in the QC conversion layer. Historical +query/blindness/subsequent-special dates and uncaptured future increments +also already trigger their refusals without a specialist flag. + A `CoverageCondition` explicitly triggers each specialist refusal. The module does not infer excluded specialist facts from ordinary earnings. Fiscal/short-year allocation helpers execute source arithmetic privately @@ -413,6 +490,43 @@ Round 2 adds these executed invariants and interface properties: | Replacing observed fact provenance with convention-filled provenance and identifiers changes no status or DLI; all identifiers remain disclosed. | `test_declared_fact_provenance_preserves_computed_status` | | UNKNOWN section 214(c) applicability preserves decided false current statuses and discloses that unknown fact. Historical DLI is bounded by None through the QC-only upper date; the envelope contains the exempt filling even with old insured work histories. A true current QC predicate requires the named applicability refusal. | `test_unknown_sspa_applicability_preserves_qc_impossibility` | +Round 3 adds these invariants: + +| Invariant | Hypothesis test | +| --- | --- | +| FRA date and quarter equal an independent implementation of Act 216(l), including both step-up bands and first/second-day birthdays. | `test_fra_date_and_quarter_match_independent_act_calendar` | +| Every supplied prior period ends no later than the month before FRA. | `test_every_supplied_prior_period_has_the_statutory_fra_cap` | +| A known current establishment at or after FRA is invalid for observed and UNKNOWN prior histories. | `test_known_establishment_at_or_after_fra_is_always_invalid` | +| A returned ongoing-period status agrees with concrete ending-quarter and continuing completions, and the returned recent/fully QC counts contain their counts; otherwise the named ending refusal applies. | `test_ongoing_period_completion_status_and_count_bounds_are_sound` | +| Proving an UNKNOWN declaration invalid implies all enumerated valid-calendar, insured-start empty/one/two-period and annual-QC fillings are invalid; a valid filling prevents that error. | `test_invalid_unknown_declaration_has_no_valid_enumerated_filling` | +| A valid long prior special period can rescue current establishment; UNKNOWN history must retain that possibility even when observed empty history would be invalid. | `test_valid_prior_freeze_filling_prevents_false_invalidity` | +| Declared ending facts and provenance round-trip, inconsistent values/provenance/convention identifiers are invalid, and the original twenty positional Person fields keep their meaning. | `test_declared_period_end_provenance_roundtrip_and_invalid_combinations` | +| Automatic simplified pre1951 refusals obey exact $400 aggregate boundaries and arise without an opt-in specialist flag. | `test_pre1951_refusal_tracks_exact_400_dollar_status_boundary` | +| Mapping order and observed/convention provenance do not change the automatic simplified-pre1951 reason. | `test_pre1951_refusal_is_independent_of_mapping_order_and_provenance` | +| Automatic pre1951 detection bounds the lower fully insured requirement from a known disability freeze at exact aggregate-dollar boundaries, even when the ordinary witness selects a higher requirement. | `test_pre1951_refusal_bounds_every_known_freeze_requirement` | +| Automatic pre1956 alternative refusals require at least 20 possible QCs and the continuous qualifying 1951 window. | `test_pre1956_refusal_requires_twenty_qcs_and_the_continuous_window` | + +The reviewer regressions additionally pin the 2026 blind-onset endpoint +case (five continuing QCs versus six if the period ends in the event +quarter), the 1960 birth FRA case (five QCs and false in October 2028), +post-FRA establishment errors, invalid-before-refusal and zero evaluator +rows, and Sam's seven elapsed-year prerequisite. Source literal tests +retain the statutory end, duration, cohort, and simplified-credit clauses. +The ending example additionally checks equal statutory status for observed +and convention-filled endings: +`test_declared_period_end_resolves_the_query_quarter_ambiguity`. + +An additional invented pre1951 case has birth February 2, 1920, eight QCs +before a valid January 1945 period, twelve QCs inside the period, and an +ending in December 1960. At February 1990 the ordinary witness has 20 QCs +against 31 required. The freeze reduces the requirement to 21, while total +pre1951 wages of $9,200 could supply 23 deemed credits. Both a supplied +prior period and a declared current period with that end automatically +refuse; neither silently returns the ordinary false result. Generated +ending years and exact cents pin the boundary, including $8,399.99 versus +$8,400 for the 21-credit requirement. This is a conservative refusal, not +a claim to adjudicate the interaction of deemed allocation and a freeze. + The reviewer's examples separately pin onset without establishment, later-quarter qualification, the event's own established period, and the 24/26 endpoint-count counterexample containing a concrete count of 23: @@ -420,9 +534,10 @@ later-quarter qualification, the event's own established period, and the `test_continuous_disability_can_first_qualify_after_medical_onset`, `test_currently_insured_excludes_period_containing_dib_event`, and `test_unknown_prerequisite_count_bounds_contain_witness_switch_fillings`. -The original assertion excluding an event's own later-ending period pinned -a source misreading. Correcting it implements 404.120(b)'s exclusion of -every intersecting established period. +Before the reviewed `d21ece2d` head, round 2 corrected an original assertion +that excluded an event's own later-ending period. That correction implements +404.120(b)'s exclusion of every intersecting established period. Round 3 +preserves the reviewed assertion. Boundary examples additionally pin actual-event windows and future-exit censoring: `test_currently_insured_uses_death_quarter_after_death`, @@ -512,9 +627,10 @@ prior period of disability established for you if by doing so you would be entitled to benefits or the amount of the benefit would be larger." RS .120 B.1.b also requires all prior periods to be used or all disregarded. Disregarding the freeze gives 20 QCs in the 40-quarter -1983Q3–1993Q2 window and the fully insured prerequisite of eight, so the -implemented result is insured. The printed used-freeze treatment has 17 -elapsed quarters, eight required, and seven available. An otherwise +1983Q3–1993Q2 window and the fully insured prerequisite of seven (the +elapsed years 1986–1992), so the implemented result is insured. The printed +eight is the used-freeze special-window requirement: that treatment has +17 elapsed quarters, eight required, and seven available. An otherwise payable invented $1,000 monthly benefit would differ by $1,000 versus zero under these insurance answers; this module computes no payment. @@ -534,6 +650,24 @@ also controls over the coordinator's reported blanket exemption; B.4.b's work-authorized exception concerns satisfying the requirement. Known applicable cases remain refused until that adjudication is implemented. +For simplified pre1951 credits, Act 213(c) says an individual "shall be +deemed to have one quarter of coverage for each $400 of his total wages +prior to 1951", subject to becoming fully insured with the resulting +credits plus post1950 credits. It states no seven-elapsed-year minimum. +RS .315 instead says "Under the 1967 Amendments, use the simplified method +if:" and "there are at least seven EYs; and"; CFR 404.110(d) uses permissive +"we may use the following rules" and also has the seven-year condition. +The evaluator refuses a potentially decisive aggregate even below seven +elapsed years. That avoids silently denying the statutory path while +filing, retroactivity, and section 227 facts remain absent. Both dates in +`test_potential_simplified_method_refuses_unresolved_seven_ey_applicability` +pin this refusal: an invented woman born February 2, 1895, with $2,400 in +1940Q1 has one ordinary QC, six deemed QCs, and a six-QC prerequisite at +February 1968. A strict seven-year eligibility reading would return false; +the broader statutory reading could return true. If an otherwise payable +invented monthly benefit were $1,000, that would be $0 versus $1,000; +this module computes neither payment and retains the named refusal. + Mutation checks are recorded in [`track_b_insured_status_mutations.json`](track_b_insured_status_mutations.json). Every recorded implementation mutation was caught and reverted. diff --git a/docs/design/track_b_insured_status_mutations.json b/docs/design/track_b_insured_status_mutations.json index dacddfd45..35be1dc76 100644 --- a/docs/design/track_b_insured_status_mutations.json +++ b/docs/design/track_b_insured_status_mutations.json @@ -1395,5 +1395,328 @@ "source_diff": "--- before_unknown_sspa_dli_lower_correction\n+++ after_unknown_sspa_dli_lower_correction\n@@ -1231,6 +1231,11 @@\n hi_censored = (\n coverage_end_month is None or coverage_end_month > month\n ) and _qid(hi_date) == _qid(month)\n+ if applicability is None:\n+ # A guaranteed historical fully insured witness also needs\n+ # resolved section214(c) facts. Keep the QC-only upper date;\n+ # false current status cannot prove a positive DLI lower date.\n+ lo_date = None\n dli = _computed(DLIRange, lo_date, hi_date, lo_censored or hi_censored)\n lo_rows, _ = _world(\n lo_person,\n", "previous_log_archive_directory": "scratch/review/pre-sspa-dli-snapshot-ab89110b" }, - "round_2_final_original_source_sha256": "3c213db1b6733d5e67566a815a93b62df58e8988dc206ae80784b494439ce3f1" + "round_2_final_original_source_sha256": "3c213db1b6733d5e67566a815a93b62df58e8988dc206ae80784b494439ce3f1", + "round_3_mutations": [ + { + "name": "query_observation_is_fabricated_as_period_end", + "before": " end = fra.replace(day=1) - timedelta(days=1)", + "after": " end = min(fra.replace(day=1) - timedelta(days=1), _qend(_qid(month)))", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_fix_round_3_periods.py -k test_ongoing_period_end_cannot_invent_a_credited_query_endpoint", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-round3", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-round3", + "PYTHONPATH": "$PWD/src:$PWD" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_3_periods.py::test_ongoing_period_end_cannot_invent_a_credited_query_endpoint" + ], + "summary": [ + "1 failed, 65 deselected in 5.57s" + ], + "log": "scratch/review/round3-periods-mutation-query-end.log", + "restored": true + }, + { + "name": "prior_disability_period_fra_cap_is_removed", + "before": " replace(p, end=min(p.end, fra_end)) if p.start < fra else p", + "after": " p", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_fix_round_3_periods.py -k test_prior_period_is_capped_at_fra_for_status_and_requirement_helper", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-round3", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-round3", + "PYTHONPATH": "$PWD/src:$PWD" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_3_periods.py::test_prior_period_is_capped_at_fra_for_status_and_requirement_helper" + ], + "summary": [ + "1 failed, 65 deselected in 13.82s" + ], + "log": "scratch/review/round3-periods-mutation-prior-fra.log", + "restored": true + }, + { + "name": "post1959_cohort_fra_is_66_instead_of_67", + "before": " elif cohort >= 1960:\n months = 804", + "after": " elif cohort >= 1960:\n months = 792", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_fix_round_3_periods.py -k test_fra_stepup_cohorts_and_first_second_birthdays_follow_416_l", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-round3", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-round3", + "PYTHONPATH": "$PWD/src:$PWD" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_3_periods.py::test_fra_stepup_cohorts_and_first_second_birthdays_follow_416_l[2-2022]" + ], + "summary": [ + "1 failed, 47 passed, 18 deselected in 7.84s" + ], + "log": "scratch/review/round3-periods-mutation-fra-cohort.log", + "restored": true + }, + { + "name": "known_current_start_at_or_after_fra_guard_is_disabled", + "before": " and self.disability_onset >= fra", + "after": " and False", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_fix_round_3_periods.py -k test_known_establishment_at_or_after_fra_is_always_invalid", + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-round3", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-round3", + "PYTHONPATH": "$PWD/src:$PWD" + }, + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_3_periods.py::test_known_establishment_at_or_after_fra_is_always_invalid" + ], + "summary": [ + "1 failed, 65 deselected in 33.30s" + ], + "log": "scratch/review/round3-periods-mutation-late-start.log", + "restored": true + }, + { + "name": "skip_impossible_unknown_prior_establishment_validation", + "before": "and _unknown_prior_history_is_empty(\n", + "after": "and False and _unknown_prior_history_is_empty(\n", + "original_source_sha256": "5bb2853d18a5a6be0db14deed45bbd3c10aa175efd9c3e7f1e5eb9b285a20c72", + "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/insured-fix-r3 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/insured-fix-r3 PYTHONPATH=/Users/maxghenis/.subfleet/worktrees/20261025-084543-trackb-fix-insured-3/src:/Users/maxghenis/.subfleet/worktrees/20261025-084543-trackb-fix-insured-3 PYTHONDONTWRITEBYTECODE=1 HYPOTHESIS_STORAGE_DIRECTORY=/Users/maxghenis/.subfleet/worktrees/20261025-084543-trackb-fix-insured-3/scratch/review/hypothesis /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_fix_round_3_validation.py -k impossible", + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_3_validation.py::test_impossible_establishment_with_unknown_prior_history_is_input_error[onset0]", + "FAILED tests/test_track_b_insured_status_fix_round_3_validation.py::test_impossible_establishment_with_unknown_prior_history_is_input_error[onset1]", + "FAILED tests/test_track_b_insured_status_fix_round_3_validation.py::test_impossible_establishment_creates_no_evaluator_denominator_row", + "FAILED tests/test_track_b_insured_status_fix_round_3_validation.py::test_impossible_unknown_history_validation_precedes_coverage_refusal" + ], + "summary": [ + "4 failed, 2 deselected in 38.23s" + ], + "log": "scratch/review/mutation-r3-validation-skip_impossible_unknown_prior_establishment_validation.log", + "restored": true + }, + { + "name": "collapse_possible_prior_history_as_empty", + "before": "and _unknown_prior_history_is_empty(\n", + "after": "and True or False and _unknown_prior_history_is_empty(\n", + "original_source_sha256": "2c2656505f5d99350cb10000f7917dd8eb4a8e10732b72fb828d8e29bdf3ef77", + "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/insured-fix-r3 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/insured-fix-r3 PYTHONPATH=/Users/maxghenis/.subfleet/worktrees/20261025-084543-trackb-fix-insured-3/src:/Users/maxghenis/.subfleet/worktrees/20261025-084543-trackb-fix-insured-3 PYTHONDONTWRITEBYTECODE=1 HYPOTHESIS_STORAGE_DIRECTORY=/Users/maxghenis/.subfleet/worktrees/20261025-084543-trackb-fix-insured-3/scratch/review/hypothesis /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_fix_round_3_validation.py -k valid_prior_freeze", + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_3_validation.py::test_valid_prior_freeze_filling_prevents_false_invalidity" + ], + "summary": [ + "1 failed, 5 deselected in 19.66s" + ], + "log": "scratch/review/mutation-r3-validation-collapse_possible_prior_history_as_empty.log", + "restored": true + }, + { + "id": "r3_simplified_pre1951_divisor", + "original": "wages // 400 + post1950", + "mutated": "wages // 401 + post1950", + "test": "test_raw_pre1951_wages_automatically_refuse_simplified_alternative", + "command": [ + "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python", + "-m", + "pytest", + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "-q", + "tests/test_track_b_insured_status_fix_round_3_coverage.py::test_raw_pre1951_wages_automatically_refuse_simplified_alternative" + ], + "result": "1 failed in 10.57s", + "exit_code": 1, + "log": "scratch/review/r3_simplified_pre1951_divisor.log", + "name": "r3_simplified_pre1951_divisor", + "before": "wages // 400 + post1950", + "after": "wages // 401 + post1950", + "returncode": 1, + "summary": [ + "1 failed in 10.57s" + ], + "restored": true, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_3_coverage.py::test_raw_pre1951_wages_automatically_refuse_simplified_alternative" + ], + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r3", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r3", + "PYTHONPATH": "$PWD/src:$PWD" + } + }, + { + "id": "r3_simplified_pre1951_unknown", + "original": "unknown_wages = any(", + "mutated": "unknown_wages = False and any(", + "test": "test_unknown_pre1951_wages_can_qualify_when_four_ordinary_qcs_cannot", + "command": [ + "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python", + "-m", + "pytest", + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "-q", + "tests/test_track_b_insured_status_fix_round_3_coverage.py::test_unknown_pre1951_wages_can_qualify_when_four_ordinary_qcs_cannot" + ], + "result": "1 failed in 7.49s", + "exit_code": 1, + "log": "scratch/review/r3_simplified_pre1951_unknown.log", + "name": "r3_simplified_pre1951_unknown", + "before": "unknown_wages = any(", + "after": "unknown_wages = False and any(", + "returncode": 1, + "summary": [ + "1 failed in 7.49s" + ], + "restored": true, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_3_coverage.py::test_unknown_pre1951_wages_can_qualify_when_four_ordinary_qcs_cannot" + ], + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r3", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r3", + "PYTHONPATH": "$PWD/src:$PWD" + } + }, + { + "id": "r3_pre1956_alternative_twenty", + "original": "len(assigned) >= 20", + "mutated": "len(assigned) >= 21", + "test": "test_pre1956_alternate_disability_path_is_detected_from_onset_and_qcs", + "command": [ + "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python", + "-m", + "pytest", + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "-q", + "tests/test_track_b_insured_status_fix_round_3_coverage.py::test_pre1956_alternate_disability_path_is_detected_from_onset_and_qcs" + ], + "result": "1 failed in 6.25s", + "exit_code": 1, + "log": "scratch/review/r3_pre1956_alternative_twenty.log", + "name": "r3_pre1956_alternative_twenty", + "before": "len(assigned) >= 20", + "after": "len(assigned) >= 21", + "returncode": 1, + "summary": [ + "1 failed in 6.25s" + ], + "restored": true, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_3_coverage.py::test_pre1956_alternate_disability_path_is_detected_from_onset_and_qcs" + ], + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/insured-r3", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/insured-r3", + "PYTHONPATH": "$PWD/src:$PWD" + } + }, + { + "name": "sam_design_fully_prerequisite_seven_becomes_eight", + "mutation_kind": "documentation", + "file": "docs/design/track_b_insured_status.md", + "before": "fully insured prerequisite of seven (the", + "after": "fully insured prerequisite of eight (the", + "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE PYTHONPATH=$PWD/src:$PWD POPULACE_DYNAMICS_PSID_DIR=/nonexistent/insured-r3-sam POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/insured-r3-sam /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status.py::test_sam_subsequent_poms_140_example_9_favorable_disregard_erratum", + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status.py::test_sam_subsequent_poms_140_example_9_favorable_disregard_erratum" + ], + "summary": [ + "1 failed in 24.93s" + ], + "log": "scratch/review/mutation-r3-sam-prerequisite.log", + "restored": true + }, + { + "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/insured-freeze-r3 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/insured-freeze-r3 PYTHONPATH=/Users/maxghenis/.subfleet/worktrees/20261025-084543-trackb-fix-insured-3/src:/Users/maxghenis/.subfleet/worktrees/20261025-084543-trackb-fix-insured-3 PYTHONDONTWRITEBYTECODE=1 HYPOTHESIS_STORAGE_DIRECTORY=/Users/maxghenis/.subfleet/worktrees/20261025-084543-trackb-fix-insured-3/scratch/review/hypothesis-freeze /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_fix_round_3_coverage.py -k 'lower_frozen or bounds_every_known_freeze'", + "returncode": 1, + "summary": [ + "3 failed, 16 deselected in 12.20s" + ], + "failed": [ + "FAILED tests/test_track_b_insured_status_fix_round_3_coverage.py::test_pre1951_refusal_considers_lower_frozen_fully_requirement[False]", + "FAILED tests/test_track_b_insured_status_fix_round_3_coverage.py::test_pre1951_refusal_considers_lower_frozen_fully_requirement[True]", + "FAILED tests/test_track_b_insured_status_fix_round_3_coverage.py::test_pre1951_refusal_bounds_every_known_freeze_requirement" + ], + "log": "scratch/review/pre1951-freeze-mutant.log", + "module_sha256": "7b39bfde6d1ebbfb1eb34494953829d4e34fecb4f52eb229b2f13af13a77cc4d", + "test_sha256": "98278b6b4d0ed0ebc6165c4dbd4a9388f66c14375f95067914c976acbd68a4a1", + "id": "r3_simplified_pre1951_freeze_requirement", + "original": "required = min(lo[6], _requirement(person, month, periods))", + "mutated": "required = max(lo[6], _requirement(person, month, periods))", + "restored_sha256": "25ea1b98acc684d0f4187de3da2fa781aeddac8d6931cf509c6344a89a57151d", + "name": "r3_simplified_pre1951_freeze_requirement", + "before": "required = min(lo[6], _requirement(person, month, periods))", + "after": "required = max(lo[6], _requirement(person, month, periods))", + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_3_coverage.py::test_pre1951_refusal_considers_lower_frozen_fully_requirement[False]", + "FAILED tests/test_track_b_insured_status_fix_round_3_coverage.py::test_pre1951_refusal_considers_lower_frozen_fully_requirement[True]", + "FAILED tests/test_track_b_insured_status_fix_round_3_coverage.py::test_pre1951_refusal_bounds_every_known_freeze_requirement" + ], + "restored": true + } + ], + "round_3_validation_restored_baseline": { + "command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/insured-fix-r3 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/insured-fix-r3 PYTHONPATH=/Users/maxghenis/.subfleet/worktrees/20261025-084543-trackb-fix-insured-3/src:/Users/maxghenis/.subfleet/worktrees/20261025-084543-trackb-fix-insured-3 PYTHONDONTWRITEBYTECODE=1 HYPOTHESIS_STORAGE_DIRECTORY=/Users/maxghenis/.subfleet/worktrees/20261025-084543-trackb-fix-insured-3/scratch/review/hypothesis /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q tests/test_track_b_insured_status_fix_round_3_validation.py", + "returncode": 0, + "failed_tests": [], + "summary": [ + "6 passed in 24.83s" + ], + "log": "scratch/review/mutation-r3-validation-restored-baseline.log" + }, + "round_3_final_source_sha256": "7a99028e7e227e3311e3f0b547e25260a4ce3c5b24bdda41a7ae53212744c6c9", + "round_3_note": "Actual mutation execution records are retained. Narrow restoration preserved disjoint concurrent edits. Each implementation mutation was caught; Sam is a documentary mutation because the existing arithmetic was correct. Final scoped gates are recorded in scratch/review/fix-round-3-report.md.", + "round_3_source_transition": { + "previous_final_source_sha256": "a4f06ba3a5883f6b8e96a7887063499bc8e49512870f986c74355106d23b1b26", + "final_source_sha256": "a0d10a7fb495ecc48ee76d2d4b77eb4d9108db311246ec498604487ef2c3c37c", + "reason": "Append three optional ending fields after all original twenty Person fields, preserving positional-call meaning; no statutory rule or default changed. Existing provenance property pins this compatibility and failed before the reorder." + }, + "round_3_additional_source_transitions": [ + { + "previous_final_source_sha256": "a0d10a7fb495ecc48ee76d2d4b77eb4d9108db311246ec498604487ef2c3c37c", + "final_source_sha256": "7a99028e7e227e3311e3f0b547e25260a4ce3c5b24bdda41a7ae53212744c6c9", + "reason": "Conservatively compare simplified pre1951 credits against every known freeze prerequisite and the six-QC bound for UNKNOWN establishment; include derived current periods. Exact cents and prior/current regressions plus a caught min-to-max mutation pin the extension." + } + ], + "round_3_exact_head_replay": { + "head": "d21ece2d44e6a65239ec3cf861970225891aef36", + "summary": [ + "10 failed in 6.19s" + ], + "restoration_exact": true, + "evidence": "scratch/review/round3-exact-head-replay.json", + "label": "Post-fix baseline replay; initial failing-first chronology remains in scratch notes." + } } diff --git a/src/populace_dynamics/track_b/insured_status.py b/src/populace_dynamics/track_b/insured_status.py index 39dd656c3..361d7659d 100644 --- a/src/populace_dynamics/track_b/insured_status.py +++ b/src/populace_dynamics/track_b/insured_status.py @@ -6,12 +6,17 @@ and 404.315/.320/.321; POMS RS 00301. Every year is declared, including zero and unknown years. Medical onset declares continuous disability through the query month; it -never establishes an administrative period of disability. Disability tests +never establishes an administrative period of disability. An established +period ends no later than the month before full retirement age; an unknown +ending is bounded rather than fabricated at the query. Disability tests scan onset and later quarters; period establishment and section 214(c) -applicability carry explicit provenance. The query month is a hypothetical -entitlement month, not medical or administrative adjudication. Annual QC assignment is -favorable and retrospective; callers must supply only information available -at their decision time. Each test returns its own assignment witness. +applicability carry explicit provenance. Impossible UNKNOWN histories are +rejected before any coverage refusal. Observable specialist credit +alternatives cannot silently produce ordinary-only uninsured answers. The +query month is a hypothetical entitlement month, not medical or +administrative adjudication. Annual QC assignment is favorable and +retrospective; callers must supply only information available at their +decision time. Each test returns its own assignment witness. All public declarations use the shared exact-type schema. Ordered sequences retain multiplicity; conditions are membership collections. Computed values, @@ -99,6 +104,7 @@ class InsuredUnsupportedReason(Enum): UNKNOWN_SSPA211 = "sspa211_applicability_unknown" CURRENT_PERIOD_HISTORY = "current_disability_period_requires_history" CURRENT_PERIOD_DLI = "ongoing_disability_period_dli_horizon_unsupported" + CURRENT_PERIOD_END = "ongoing_disability_period_end_decides_status" TOTALIZATION = "totalization_credits_unsupported" DEEMED_FULLY_INSURED = "deemed_fully_insured_unsupported" TRANSITIONAL_INSURED = "transitional_insured_unsupported" @@ -271,6 +277,11 @@ class Person: sspa211_applies: bool | None = None sspa211_provenance: EarningsProvenance = EarningsProvenance.UNKNOWN sspa211_convention_id: str | None = None + current_disability_period_end: date | None = None + current_disability_period_end_provenance: EarningsProvenance = ( + EarningsProvenance.UNKNOWN + ) + current_disability_period_end_convention_id: str | None = None def __post_init__(self): _fact_provenance( @@ -314,6 +325,30 @@ def __post_init__(self): raise InvalidFamilyInput( "Current established period requires medical onset" ) + _fact_provenance( + self.current_disability_period_end_provenance, + self.current_disability_period_end_convention_id, + "current disability period end", + ) + if ( + self.current_disability_period_end_provenance + is EarningsProvenance.UNKNOWN + ) != (self.current_disability_period_end is None): + raise InvalidFamilyInput( + "Current period end must match provenance" + ) + if self.current_disability_period_end is not None: + if not self.current_disability_period_established: + raise InvalidFamilyInput( + "Period end requires established period" + ) + end = self.current_disability_period_end + if end.day != calendar.monthrange(end.year, end.month)[1]: + raise InvalidFamilyInput( + "Period end must close a calendar month" + ) + if end < self.disability_onset: + raise InvalidFamilyInput("Current period ends before onset") if not 1870 <= self.birth_date.year <= 9900: raise InvalidFamilyInput("Birth year outside supported calendar") if self.birth_date < date(1913, 1, 2) and self.sex is None: @@ -327,8 +362,27 @@ def __post_init__(self): and self.disability_onset > self.death_date ): raise InvalidFamilyInput("Disability onset follows death") - periods = sorted(self.prior_disability_periods, key=lambda p: p.start) + fra = _fra_date(self) + if ( + self.current_disability_period_established + and self.disability_onset >= fra.replace(day=1) + ): + raise InvalidFamilyInput( + "Established period begins after its statutory FRA end" + ) + fra_end = fra.replace(day=1) - timedelta(days=1) + periods = sorted( + ( + replace(p, end=min(p.end, fra_end)) if p.start < fra else p + for p in self.prior_disability_periods + ), + key=lambda p: p.start, + ) for i, period in enumerate(periods): + if period.start >= fra or period.start > fra_end: + raise InvalidFamilyInput( + "Disability period begins at or after FRA" + ) if period.start < self.birth_date or ( self.death_date is not None and period.end > self.death_date ): @@ -461,6 +515,7 @@ def fully_insured_requirement(person: Person, month: date) -> int: ) if ( person.disability_onset is not None + and person.disability_onset < _fra_date(person).replace(day=1) and person.current_disability_period_established is not False ): _refuse( @@ -615,6 +670,97 @@ def _coverage_checks(person, years, month, credits): ) +def _observable_coverage_paths( + person, years, month, exit_month, kind, lo, upper +): + """Refuse favorable specialist paths revealed by ordinary declarations. + + Act 213(c), 404.110(d), and RS 00301.315 make the pre1951 aggregate + method available independently of an optional specialist flag. Its + application, retroactivity and section227 conditions are not declared. + Act213(c) has no seven-EY limitation, unlike 404.110(d) and RS .315; + a potentially decisive path is refused without deciding that conflict. + Direct QC declarations supply credited quarters, not raw wage totals. + RS 00301.480 likewise reveals a possible pre1956 alternate disability + path from onset and earnings; its application facts remain unmodeled. + """ + if lo[0]: + return + if kind is InsuredTest.FULLY: + before1951 = {year: row for year, row in years.items() if year < 1951} + if not before1951: + return + wages = sum( + ( + sum(row.quarterly_wages) + for row in before1951.values() + if row.quarterly_wages is not None + ), + Fraction(0), + ) + unknown_wages = any( + row.provenance is EarningsProvenance.UNKNOWN + for row in before1951.values() + ) + rows, _ = _world(person, upper, _qid(month), exit_month, False) + post1950 = sum( + len(_assign_qcs(*row)) + for year, row in rows.items() + if year >= 1951 + ) + periods = tuple( + (period.start, period.end) + for period in person.prior_disability_periods + ) + # The favorable ordinary witness may disregard a freeze whose + # lower prerequisite would favor the simplified aggregate instead. + # Use every known period, including a derived current period, and + # the universal six-QC lower bound for unresolved applicability. + required = min(lo[6], _requirement(person, month, periods)) + if ( + person.prior_disability_periods_provenance + is EarningsProvenance.UNKNOWN + or person.disability_onset is not None + and person.disability_onset < _fra_date(person).replace(day=1) + and person.current_disability_period_provenance + is EarningsProvenance.UNKNOWN + ): + required = 6 + if unknown_wages or ( + wages >= 400 and wages // 400 + post1950 >= required + ): + _refuse( + InsuredUnsupportedReason.SIMPLIFIED_PRE1951, + "Pre1951 wages may establish fully insured status under " + "Act213(c); filing and retroactivity facts are unmodeled", + ) + elif ( + kind is InsuredTest.DISABILITY + and person.disability_onset is not None + and person.disability_onset < date(1956, 1, 1) + ): + first = max(_qid(person.disability_onset), 1952 * 4 + 2) + last = min(_qid(month), 1955 * 4 + 3) + for quarter in range(first, last + 1): + rows, _ = _world(person, upper, quarter, exit_month, False) + continuous = tuple(range(1951 * 4, quarter)) + assigned = { + qc + for row in rows.values() + for qc in _assign_qcs(*row, window=continuous) + } + if ( + len(assigned) >= 20 + and len(continuous) >= 6 + and set(continuous) <= assigned + ): + _refuse( + InsuredUnsupportedReason.DISABILITY_BEFORE_1956, + "Onset and QCs allow the RS00301.480 alternate test; " + "application conditions are unmodeled", + ) + + def _credits(year, row, upper): if row.provenance is EarningsProvenance.UNKNOWN: return (), 4 if upper else 0 @@ -851,7 +997,59 @@ def _witness(person, credits, at, exit_month, kind, *, onset=True): return best[1] -def _fra_quarter(person): +def _unknown_prior_history_is_empty(person, credits, month, exit_month): + """Prove infeasibility of the earliest nonempty prior period only. + + The earliest period must begin insured without any earlier exclusions + (404.320(b)(2), 404.321(a)), fit before onset and FRA, and leave five + months before its ending month (404.320(b)(4)). Upper-credit witnesses + deliberately overapproximate possibility. A surviving quarter proves + no actual history; it only prevents an invalid-input conclusion. + """ + if person.disability_onset is None: + return False + latest_end = min( + person.disability_onset - timedelta(days=1), + _fra_date(person).replace(day=1) - timedelta(days=1), + ) + if latest_end < person.birth_date: + return True + positive_years = [ + year + for year, (fixed, flexible) in credits.items() + if fixed or flexible + ] + if not positive_years: + return True + first = max(_qid(person.birth_date), min(positive_years) * 4) + plain = replace( + person, + prior_disability_periods=(), + prior_disability_periods_provenance=EarningsProvenance.OBSERVED, + prior_disability_periods_convention_id=None, + ) + last_month = latest_end.year * 12 + latest_end.month - 1 + for quarter in range(first, _qid(latest_end) + 1): + start = max(person.birth_date, _qdate(quarter)) + if start >= _fra_date(person): + break + # Permissive about partial first/last months: only use this bound + # to prove impossibility, never to establish a period or its dates. + if start.year * 12 + start.month - 1 + 5 > last_month: + break + if _witness( + plain, + credits, + start, + exit_month, + InsuredTest.DISABILITY, + onset=False, + )[0]: + return False + return True + + +def _fra_date(person): cohort = (person.birth_date - timedelta(days=1)).year months = 780 if 1938 <= cohort <= 1942: @@ -865,7 +1063,11 @@ def _fra_quarter(person): index = person.birth_date.year * 12 + person.birth_date.month - 1 + months year, month = divmod(index, 12) day = min(person.birth_date.day, calendar.monthrange(year, month + 1)[1]) - return _qid(date(year, month + 1, day) - timedelta(days=1)) + return date(year, month + 1, day) - timedelta(days=1) + + +def _fra_quarter(person): + return _qid(_fra_date(person)) def _last_insured(person, credits, month, exit_month): @@ -911,9 +1113,11 @@ def _last_insured(person, credits, month, exit_month): def _events(person, month, kind): if kind is InsuredTest.DISABILITY and person.disability_onset is not None: # 404.131(a): onset quarter OR a later quarter while disabled. + last = _qid(month) + if person.current_disability_period_established: + last = min(last, _fra_quarter(person)) return tuple( - _qdate(q) - for q in range(_qid(person.disability_onset), _qid(month) + 1) + _qdate(q) for q in range(_qid(person.disability_onset), last + 1) ) if kind is InsuredTest.CURRENTLY: return tuple( @@ -940,11 +1144,27 @@ def _decision_witness(person, credits, month, exit_month, kind): return best, qualifying -def _with_current_period(person, credits, month, exit_month): +def _period_end_unknown(person, month): + return ( + person.current_disability_period_established + and person.current_disability_period_end is None + and month < _fra_date(person).replace(day=1) + and ( + person.death_date is None + or person.death_date.replace(day=1) > month + ) + ) + + +def _with_current_period( + person, credits, month, exit_month, *, earliest_end=False +): if not person.current_disability_period_established: return person, None + fra = _fra_date(person) + horizon = min(month, fra.replace(day=1)) witness, quarter = _decision_witness( - person, credits, month, exit_month, InsuredTest.DISABILITY + person, credits, horizon, exit_month, InsuredTest.DISABILITY ) if not witness[0]: raise InvalidFamilyInput( @@ -958,13 +1178,27 @@ def _with_current_period(person, credits, month, exit_month): if _qid(quarter) == _qid(person.disability_onset) else quarter ) - end = date( - month.year, - month.month, - calendar.monthrange(month.year, month.month)[1], - ) + # 416(i)(2)(B)/(D), 404.321: the query is an observation cut-off, + # never an ending fact. Without an end declaration, compare completion + # in this quarter with continuation to the statutory FRA boundary. + end = fra.replace(day=1) - timedelta(days=1) + if start >= fra or start > end: + raise InvalidFamilyInput("Established period begins at or after FRA") + if person.current_disability_period_end is not None: + end = min(end, person.current_disability_period_end) + elif earliest_end: + end = min( + end, + date( + month.year, + month.month, + calendar.monthrange(month.year, month.month)[1], + ), + ) if person.death_date is not None: end = min(end, person.death_date) + if end < start: + raise InvalidFamilyInput("Current period ends before insured start") period = DisabilityPeriod(start, end) return ( replace( @@ -1002,8 +1236,12 @@ def insured_status( Medical onset means continuously disabled through this query and never establishes a period. Declare establishment, prior-period provenance, and section214(c) applicability; UNKNOWN never silently means none. + Declare an administrative ending with its provenance when known. An + ongoing period is bounded by possible endings, with a named refusal if + the ending changes a requested status, and is always capped before FRA. Each disability window ends at its tested quarter, from onset through query, and the first insured quarter supplies the witness (404.131). + Impossible establishment is an input error even with UNKNOWN history. No entry date, imputation, or pre-entry zero convention exists. """ _validate_history( @@ -1022,9 +1260,11 @@ def insured_status( ) current_unknown = ( person.disability_onset is not None + and person.disability_onset < _fra_date(person).replace(day=1) and person.current_disability_period_provenance is EarningsProvenance.UNKNOWN ) + end_unknown = _period_end_unknown(person, month) and not prior_unknown max_rows, _ = _world( person, upper, @@ -1038,6 +1278,27 @@ def insured_status( raise InvalidFamilyInput( "Established current period requires at least six lifetime QCs" ) + if ( + person.current_disability_period_established + and prior_unknown + and _unknown_prior_history_is_empty( + person, upper, month, coverage_end_month + ) + ): + # Empty is the only possible prior history. Validate establishment + # in that concrete world before retaining any coverage refusal. + # Keep the caller's UNKNOWN provenance and conservative output + # envelope if it is valid; no observed fact is invented here. + plain = replace( + person, + prior_disability_periods_provenance=EarningsProvenance.OBSERVED, + prior_disability_periods_convention_id=None, + ) + _with_current_period(plain, upper, month, coverage_end_month) + if person.current_disability_period_established and not prior_unknown: + # Even the most favorable earnings completion must supply a legal + # insured start before FRA. Input errors precede coverage refusals. + _with_current_period(person, upper, month, coverage_end_month) _coverage_checks(person, years, month, totalization_credits) applicability = _sspa211_applicability(person) # Known applicable cases require unimplemented work-authorization/visa @@ -1092,8 +1353,14 @@ def insured_status( person, lower, month, coverage_end_month ) hi_person, hi_start = ( - _with_current_period(person, upper, month, coverage_end_month) - if unknown + _with_current_period( + person, + upper, + month, + coverage_end_month, + earliest_end=end_unknown, + ) + if unknown or end_unknown else (lo_person, lo_start) ) if lo_start != hi_start: @@ -1106,6 +1373,7 @@ def insured_status( if ( person.current_disability_period_established and not prior_unknown + and end_unknown and coverage_end_month is not None and coverage_end_month <= month and _dli_cap(person, month, coverage_end_month) > _qend(_qid(month)) @@ -1140,9 +1408,41 @@ def insured_status( _decision_witness( decision_hi_person, upper, month, coverage_end_month, kind ) - if unknown + if unknown or end_unknown else (lo, lo_quarter) ) + if end_unknown: + same_earnings_end, _ = _decision_witness( + ( + person + if kind is InsuredTest.DISABILITY + else _with_current_period( + person, + lower, + month, + coverage_end_month, + earliest_end=True, + )[0] + ), + lower, + month, + coverage_end_month, + kind, + ) + if lo[0] != same_earnings_end[0]: + _refuse( + InsuredUnsupportedReason.CURRENT_PERIOD_END, + f"Unobserved statutory period end decides {kind.value}", + ) + _observable_coverage_paths( + decision_lo_person, + years, + month, + coverage_end_month, + kind, + lo, + upper, + ) if lo[0] != hi[0]: _refuse( InsuredUnsupportedReason.UNKNOWN_EARNINGS, @@ -1178,6 +1478,8 @@ def insured_status( broad = ( prior_unknown or current_unknown + or end_unknown + and bool(unknown) or bool(unknown) and ( bool(person.prior_disability_periods) @@ -1223,7 +1525,7 @@ def insured_status( ) hi_date, hi_censored = ( _last_insured(hi_person, upper, month, coverage_end_month) - if unknown + if unknown or end_unknown else (lo_date, lo_censored) ) if (prior_unknown or current_unknown) and maximum_qcs >= 6: @@ -1260,6 +1562,7 @@ def insured_status( ("prior_disability_periods", prior_unknown), ("current_disability_period", current_unknown), ("current_disability_period_start", uncertain_current_start), + ("current_disability_period_end", end_unknown), ("sspa211_applicability", applicability is None), ) if missing @@ -1275,6 +1578,10 @@ def insured_status( "current_disability_period", person.current_disability_period_convention_id, ), + ( + "current_disability_period_end", + person.current_disability_period_end_convention_id, + ), ("sspa211_applicability", person.sspa211_convention_id), ) if identifier is not None diff --git a/tests/README-tiers.md b/tests/README-tiers.md index cf14fc6ac..d9a347da7 100644 --- a/tests/README-tiers.md +++ b/tests/README-tiers.md @@ -39,9 +39,9 @@ pytest --collect-only -q -m oracle_policyengine | tail -1 | Tier | Tests at HEAD | |---|---:| -| `unit` | 19,723 | +| `unit` | 19,826 | | `artifact` | 4,271 | | `integration_psid` | 1,471 | | `reproduction_legacy` | 520 | | `oracle_policyengine` | 308 | -| **Total** | **26,293** | +| **Total** | **26,396** | diff --git a/tests/data/track_b/insured_status_examples.yaml b/tests/data/track_b/insured_status_examples.yaml index 1c370286b..86812715b 100644 --- a/tests/data/track_b/insured_status_examples.yaml +++ b/tests/data/track_b/insured_status_examples.yaml @@ -474,7 +474,7 @@ examples: lower_wages: '5500' lower_qcs: 13 coverage: refused - note: Simplified pre-1951 aggregate credits require the named special credit condition. + note: Potentially decisive supplied pre-1951 wages trigger the named refusal automatically; filing and allocation facts remain unmodeled. refusal_reason: simplified_pre1951_unsupported - id: poms_315_retroactive source: poms_rs_00301_315 diff --git a/tests/test_track_b_insured_status.py b/tests/test_track_b_insured_status.py index 8e95db22f..ab6cd1d7f 100644 --- a/tests/test_track_b_insured_status.py +++ b/tests/test_track_b_insured_status.py @@ -959,6 +959,14 @@ def test_sam_subsequent_poms_140_example_9_favorable_disregard_erratum(): assert result.disability.insured assert result.disability.rule == "disability_20_of_40" assert result.disability.required == result.disability.qc_count_lower == 20 + assert result.disability.fully_required == 7 + design = ( + Path(__file__).parents[1] / "docs/design/track_b_insured_status.md" + ).read_text() + assert ( + "fully insured prerequisite of seven (the elapsed years " + "1986–1992)" in " ".join(design.split()) + ) assert tuple( q for q in result.disability.assigned_quarters if q // 4 == 1983 ) == (qid(1983, 3), qid(1983, 4)) diff --git a/tests/test_track_b_insured_status_fix_round_3_coverage.py b/tests/test_track_b_insured_status_fix_round_3_coverage.py new file mode 100644 index 000000000..441c37891 --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_3_coverage.py @@ -0,0 +1,372 @@ +"""Statutory conformance: observable specialist coverage boundaries. + +Invented records and captured RS 00301.315 figures only. No population, +behavioral, payment, or forecast claim. +""" + +from dataclasses import replace +from datetime import date +from fractions import Fraction + +import pytest +from hypothesis import example, given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as i +from populace_dynamics.track_b.gross_benefits import InvalidFamilyInput +from tests.test_track_b_insured_status import declared, history +from tests.test_track_b_insured_status_sources import source_text + +PROPERTY = settings(max_examples=30, deadline=None) + + +def _person(birth=date(1896, 2, 2), **values): + declarations = { + "sex": i.Sex.FEMALE, + "prior_disability_periods_provenance": i.EarningsProvenance.OBSERVED, + "current_disability_period_established": False, + "current_disability_period_provenance": i.EarningsProvenance.OBSERVED, + "sspa211_applies": False, + "sspa211_provenance": i.EarningsProvenance.OBSERVED, + } + declarations.update(values) + return i.Person(birth, **declarations) + + +def _wages(amount): + return i.CoverageYear( + i.EarningsProvenance.OBSERVED, + quarterly_wages=( + Fraction(amount), + Fraction(0), + Fraction(0), + Fraction(0), + ), + ) + + +def _refusal(person, years, month, *, test=i.InsuredTest.FULLY): + with pytest.raises(i.InsuredConfigurationUnsupported) as error: + i.insured_status(person, years, month, test=test) + return error.value.reason + + +def test_raw_pre1951_wages_automatically_refuse_simplified_alternative(): + """Executed reviewer case: ordinary one QC versus seven deemed QCs.""" + month = date(1968, 2, 1) + person = _person(rib_entitlement_month=month) + years = history(person, month) + years[1940] = _wages(2800) + assert person.conditions == frozenset() + assert i.fully_insured_requirement(person, month) == 7 + assert Fraction(2800) // 400 == 7 + assert ( + _refusal(person, years, month) + is i.InsuredUnsupportedReason.SIMPLIFIED_PRE1951 + ) + + +def test_unknown_pre1951_wages_can_qualify_when_four_ordinary_qcs_cannot(): + month = date(1968, 2, 1) + person = _person() + years = history(person, month) + years[1940] = declared(provenance=i.EarningsProvenance.UNKNOWN, year=1940) + assert ( + _refusal(person, years, month) + is i.InsuredUnsupportedReason.SIMPLIFIED_PRE1951 + ) + + +@pytest.mark.parametrize("amount,refuses", [(5700, True), (5500, False)]) +def test_poms315_john_doe_aggregate_boundary_without_specialist_flag( + amount, refuses +): + """RS .315 C.1: 23+14=37; 23+13=36 invokes ordinary-credit fallback.""" + person = _person(date(1926, 9, 8)) + month = date(1991, 9, 1) + years = history( + person, month, {**{year: 4 for year in range(1980, 1985)}, 1985: 3} + ) + for year in (1948, 1949): + years[year] = _wages(1900) + years[1950] = _wages(amount - 3800) + assert i.fully_insured_requirement(person, month) == 37 + assert amount // 400 == (14 if refuses else 13) + if refuses: + assert ( + _refusal(person, years, month) + is i.InsuredUnsupportedReason.SIMPLIFIED_PRE1951 + ) + else: + result = i.insured_status( + person, years, month, test=i.InsuredTest.FULLY + ) + assert not result.fully.insured + assert result.fully.qc_count_lower == 26 + + +@PROPERTY +@given(st.integers(min_value=0, max_value=299999)) +def test_pre1951_refusal_tracks_exact_400_dollar_status_boundary(cents): + person = _person() + month = date(1968, 2, 1) + years = history(person, month) + years[1940] = _wages(Fraction(cents, 100)) + if cents >= 280000: + assert ( + _refusal(person, years, month) + is i.InsuredUnsupportedReason.SIMPLIFIED_PRE1951 + ) + else: + result = i.insured_status( + person, years, month, test=i.InsuredTest.FULLY + ) + assert not result.fully.insured + assert result.fully.qc_count_lower == int(cents >= 5000) + + +@PROPERTY +@given(st.integers(min_value=2800, max_value=2999), st.integers(0, 1)) +def test_pre1951_refusal_is_independent_of_mapping_order_and_provenance( + wages, convention +): + person = _person() + month = date(1968, 2, 1) + years = history(person, month) + row = _wages(wages) + if convention: + row = replace( + row, + provenance=i.EarningsProvenance.CONVENTION_FILLED, + convention_id="invented-wages", + ) + years[1940] = row + forward = _refusal(person, years, month) + reverse = _refusal(person, dict(reversed(tuple(years.items()))), month) + assert forward is reverse is i.InsuredUnsupportedReason.SIMPLIFIED_PRE1951 + + +def test_pre1951_alternative_does_not_change_already_fully_insured_status(): + person = _person() + month = date(1968, 2, 1) + years = history(person, month, {1960: 4, 1961: 3}) + years[1940] = _wages(2800) + result = i.insured_status(person, years, month, test=i.InsuredTest.FULLY) + assert result.fully.insured + assert result.fully.qc_count_lower == 8 + + +@pytest.mark.parametrize( + "test", [i.InsuredTest.CURRENTLY, i.InsuredTest.DISABILITY] +) +def test_simplified_pre1951_credits_do_not_apply_to_other_requested_tests( + test, +): + person = _person() + month = date(1968, 2, 1) + years = history(person, month) + years[1940] = _wages(2800) + result = i.insured_status(person, years, month, test=test) + assert not getattr(result, test.value).insured + + +@pytest.mark.parametrize("month", [date(1968, 2, 1), date(1992, 6, 1)]) +def test_potential_simplified_method_refuses_unresolved_seven_ey_applicability( + month, +): + person = _person(date(1895, 2, 2)) + years = history(person, month) + years[1940] = _wages(2400) + assert i.fully_insured_requirement(person, month) == 6 + assert ( + _refusal(person, years, month) + is i.InsuredUnsupportedReason.SIMPLIFIED_PRE1951 + ) + + +def test_raw_pre1951_refusal_follows_complete_input_validation(): + person = _person() + month = date(1968, 2, 1) + years = history(person, month) + years[1940] = _wages(2800) + del years[1951] + with pytest.raises(InvalidFamilyInput): + i.insured_status(person, years, month, test=i.InsuredTest.FULLY) + + +def test_pre1956_alternate_disability_path_is_detected_from_onset_and_qcs(): + person = _person(date(1900, 2, 2), disability_onset=date(1952, 7, 15)) + month = date(1968, 2, 1) + years = history( + person, month, {1938: 4, 1939: 4, 1940: 4, 1941: 2, 1951: 4, 1952: 2} + ) + assert ( + _refusal(person, years, month, test=i.InsuredTest.DISABILITY) + is i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956 + ) + + +def test_pre1956_onset_without_twenty_possible_qcs_needs_no_special_refusal(): + person = _person(date(1900, 2, 2), disability_onset=date(1952, 7, 15)) + month = date(1968, 2, 1) + years = history(person, month, {1951: 4, 1952: 2}) + result = i.insured_status( + person, years, month, test=i.InsuredTest.DISABILITY + ) + assert not result.disability.insured + + +@PROPERTY +@given(st.integers(0, 16), st.lists(st.booleans(), min_size=6, max_size=6)) +@example(14, [True] * 6) +@example(13, [True] * 6) +@example(16, [True, True, False, True, True, True]) +def test_pre1956_refusal_requires_twenty_qcs_and_the_continuous_window( + earlier, continuous +): + person = _person(date(1900, 2, 2), disability_onset=date(1952, 7, 15)) + month = date(1968, 2, 1) + counts = { + year: min(4, max(0, earlier - 4 * n)) + for n, year in enumerate(range(1938, 1942)) + } + years = history(person, month, counts) + for year, flags in ( + (1951, continuous[:4]), + (1952, continuous[4:] + [False, False]), + ): + years[year] = i.CoverageYear( + i.EarningsProvenance.OBSERVED, qc_quarters=tuple(flags) + ) + if earlier >= 14 and all(continuous): + assert ( + _refusal(person, years, month, test=i.InsuredTest.DISABILITY) + is i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956 + ) + else: + result = i.insured_status( + person, years, month, test=i.InsuredTest.DISABILITY + ) + assert not result.disability.insured + + +def test_observable_specialist_rules_and_worked_figures_are_in_captures(): + statute = source_text("lii_usc_42_413") + assert ( + "an individual shall be deemed to have one quarter of coverage " + "for each $400 of his total wages prior to 1951" + ) in statute + regulation = source_text("ecfr_20cfr404_subpart_b") + assert "if you have at least 7 elapsed years" in regulation + assert "If you file an application in June 1992 or later" in regulation + simplified = source_text("poms_rs_00301_315") + for quote in ( + "Under the 1967 Amendments, use the simplified method if:", + "there are at least seven EYs; and", + "The 1990 Amendments eliminated the seven EY test.", + "The simplified method does not apply to disability claims.", + "applications effectively filed 06/1992 or later.", + "$5,700 divided by $400 = 14", + "$5,500", + "13 QCs", + "23 QCs after 1950", + "37 QCs", + ): + assert quote in simplified + alternate = source_text("poms_rs_00301_480") + for quote in ( + "the wage earner had at least 20 quarters of coverage (QC) by the end of that quarter;", + "all quarters beginning with 03/51 up to (but not including) that quarter are QCs and there are at least six such QCs.", + "the last day on which it can begin is 12/31/55.", + ): + assert quote in alternate + + +def _simplified_with_freeze(ending_year=1960, cents=920000, *, current=False): + period = i.DisabilityPeriod( + date(1945, 1, 1), date(ending_year, 12, 31), special_insured=True + ) + declarations = {"prior_disability_periods": (period,)} + if current: + declarations = { + "disability_onset": period.start, + "current_disability_period_established": True, + "current_disability_period_end": period.end, + "current_disability_period_end_provenance": ( + i.EarningsProvenance.OBSERVED + ), + } + person = _person(date(1920, 2, 2), **declarations) + month = date(1990, 2, 1) + years = history(person, month) + # These eight quarters establish a valid under31 period in 1945Q1. + for year, amounts in { + 1941: (0, 50, 50, 50), + 1942: (50, 50, 50, 50), + 1943: (50, 0, 0, 0), + }.items(): + years[year] = i.CoverageYear( + i.EarningsProvenance.OBSERVED, + quarterly_wages=tuple(map(Fraction, amounts)), + ) + # Equal fractions preserve twelve ordinary QCs and the exact aggregate. + amount = (Fraction(cents, 100) - 400) / 12 + for year in (1946, 1947, 1948): + years[year] = i.CoverageYear( + i.EarningsProvenance.OBSERVED, + quarterly_wages=(amount,) * 4, + ) + return person, years, month + + +@pytest.mark.parametrize("current", [False, True]) +def test_pre1951_refusal_considers_lower_frozen_fully_requirement(current): + person, years, month = _simplified_with_freeze(current=current) + credits = { + year: i._credits(year, row, False) for year, row in years.items() + } + plain = replace( + person, + prior_disability_periods=(), + current_disability_period_established=False, + current_disability_period_end=None, + current_disability_period_end_provenance=i.EarningsProvenance.UNKNOWN, + ) + prior = i._witness( + plain, credits, date(1945, 1, 1), None, i.InsuredTest.DISABILITY + ) + assert prior[0] and prior[1:3] == (8, 8) + assert prior[5] == "under31_special" + ordinary = i._witness(plain, credits, month, None, i.InsuredTest.FULLY) + assert not ordinary[0] and ordinary[1:3] == (20, 31) + frozen_required = i._requirement( + person, month, ((date(1945, 1, 1), date(1960, 12, 31)),) + ) + assert frozen_required == 21 + assert Fraction(9200) // 400 == 23 + assert ( + _refusal(person, years, month) + is i.InsuredUnsupportedReason.SIMPLIFIED_PRE1951 + ) + + +@PROPERTY +@given(st.integers(1953, 1962), st.integers(100000, 1239999)) +@example(1960, 839999) +@example(1960, 840000) +def test_pre1951_refusal_bounds_every_known_freeze_requirement( + ending_year, cents +): + person, years, month = _simplified_with_freeze(ending_year, cents) + required = max(6, 31 - (ending_year - 1950)) + assert i.fully_insured_requirement(person, month) == required + if cents // 40000 >= required: + assert ( + _refusal(person, years, month) + is i.InsuredUnsupportedReason.SIMPLIFIED_PRE1951 + ) + else: + result = i.insured_status( + person, years, month, test=i.InsuredTest.FULLY + ) + assert not result.fully.insured diff --git a/tests/test_track_b_insured_status_fix_round_3_periods.py b/tests/test_track_b_insured_status_fix_round_3_periods.py new file mode 100644 index 000000000..fccea1596 --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_3_periods.py @@ -0,0 +1,498 @@ +"""Statutory conformance: ongoing period endpoints and retirement limits. + +Invented cases and captured statutory rules only; no population, behavioral, +or forecast claim. +""" + +from dataclasses import replace +from datetime import date + +import pytest +from hypothesis import example, given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as i +from populace_dynamics.track_b.gross_benefits import InvalidFamilyInput +from tests.test_track_b_insured_status import history + +OBSERVED = i.EarningsProvenance.OBSERVED + + +def _person(birth=date(2000, 2, 2), **facts): + return i.Person( + birth, + prior_disability_periods_provenance=OBSERVED, + current_disability_period_established=True, + current_disability_period_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + **facts, + ) + + +def _endpoint_case(): + person = _person( + disability_onset=date(2022, 1, 15), + statutory_blindness=True, + dib_entitlement_month=date(2026, 1, 1), + ) + month = date(2026, 3, 1) + years = history(person, month, {2017: 1, 2020: 4, 2021: 1, 2026: 1}) + return person, years, month + + +def test_ongoing_period_end_cannot_invent_a_credited_query_endpoint(): + person, years, month = _endpoint_case() + with pytest.raises(i.InsuredConfigurationUnsupported) as error: + i.insured_status(person, years, month, test=i.InsuredTest.CURRENTLY) + assert error.value.reason.value == ( + "ongoing_disability_period_end_decides_status" + ) + later = i.insured_status( + person, years, date(2026, 4, 1), test=i.InsuredTest.CURRENTLY + ) + assert not later.currently.insured + assert later.currently.qc_count_lower == 5 + assert later.currently.window == tuple(range(2018 * 4 + 3, 2022 * 4)) + + +def _fra_person(onset=date(2026, 1, 15), blind=False): + return _person( + date(1960, 1, 2), + disability_onset=onset, + statutory_blindness=blind, + rib_entitlement_month=date(2028, 10, 1), + ) + + +def test_current_period_ends_before_fra_even_when_medical_disability_continues(): + person = _fra_person() + month = date(2028, 10, 1) + years = history(person, month, {y: 4 for y in range(2016, 2026)}) + result = i.insured_status( + person, years, month, test=i.InsuredTest.CURRENTLY + ) + assert not result.currently.insured + assert result.currently.qc_count_lower == 5 + + +def test_known_established_period_cannot_begin_at_or_after_fra(): + with pytest.raises(InvalidFamilyInput): + person = _fra_person(date(2028, 1, 15), True) + month = date(2028, 10, 1) + years = history(person, month, {y: 4 for y in range(2016, 2026)}) + i.insured_status(person, years, month, test=i.InsuredTest.FULLY) + + +def test_post_fra_establishment_is_invalid_before_unknown_period_refusal(): + with pytest.raises(InvalidFamilyInput): + person = replace( + _fra_person(date(2028, 1, 15), True), + prior_disability_periods_provenance=i.EarningsProvenance.UNKNOWN, + ) + i.fully_insured_requirement(person, date(2028, 10, 1)) + + +def test_declared_period_end_resolves_the_query_quarter_ambiguity(): + person, years, month = _endpoint_case() + ended = replace( + person, + current_disability_period_end=date(2026, 3, 31), + current_disability_period_end_provenance=OBSERVED, + ) + continuing = replace( + ended, current_disability_period_end=date(2026, 6, 30) + ) + first = i.insured_status(ended, years, month, test=i.InsuredTest.CURRENTLY) + second = i.insured_status( + continuing, years, month, test=i.InsuredTest.CURRENTLY + ) + assert first.currently.insured + assert first.currently.qc_count_lower == 6 + assert not second.currently.insured + assert second.currently.qc_count_lower == 5 + assert first.unknown_facts == second.unknown_facts == () + conventional = replace( + continuing, + current_disability_period_end_provenance=( + i.EarningsProvenance.CONVENTION_FILLED + ), + current_disability_period_end_convention_id="invented-end-convention", + ) + value = i.insured_status( + conventional, years, month, test=i.InsuredTest.CURRENTLY + ) + assert value.currently == second.currently + assert value.convention_facts["current_disability_period_end"] == ( + "invented-end-convention" + ) + + +@pytest.mark.parametrize( + "facts", + [ + {"current_disability_period_end": date(2026, 3, 31)}, + {"current_disability_period_end_provenance": OBSERVED}, + { + "current_disability_period_end": date(2026, 3, 1), + "current_disability_period_end_provenance": OBSERVED, + }, + { + "current_disability_period_end": date(2021, 12, 31), + "current_disability_period_end_provenance": OBSERVED, + }, + ], +) +def test_current_period_end_requires_consistent_month_end_and_provenance( + facts, +): + person, _, _ = _endpoint_case() + with pytest.raises(InvalidFamilyInput): + replace(person, **facts) + + +def _act_fra(birth): + """Independent 416(l)(1)-(3) calculation from attainment of age62.""" + import calendar + from datetime import timedelta + + early = date(birth.year + 62, birth.month, birth.day) - timedelta(days=1) + if early.year < 2000: + months = 65 * 12 + elif early.year < 2005: + months = 65 * 12 + 2 * (early.year - 1999) + elif early.year < 2017: + months = 66 * 12 + elif early.year < 2022: + months = 66 * 12 + 2 * (early.year - 2016) + else: + months = 67 * 12 + year, month = divmod(birth.year * 12 + birth.month - 1 + months, 12) + day = min(birth.day, calendar.monthrange(year, month + 1)[1]) + return date(year, month + 1, day) - timedelta(days=1) + + +@pytest.mark.parametrize("early_year", range(1999, 2023)) +@pytest.mark.parametrize("day", [1, 2]) +def test_fra_stepup_cohorts_and_first_second_birthdays_follow_416_l( + early_year, day +): + birth = date(early_year - 62, 1, day) + person = _person(birth, disability_onset=date(1990, 1, 15)) + assert i._fra_date(person) == _act_fra(birth) + expected = _act_fra(birth) + assert ( + i._fra_quarter(person) == expected.year * 4 + (expected.month - 1) // 3 + ) + + +@settings(max_examples=35, deadline=None) +@given( + year=st.integers(1914, 1970), + month=st.integers(1, 12), + day=st.sampled_from([1, 2]), +) +def test_fra_date_and_quarter_match_independent_act_calendar(year, month, day): + birth = date(year, month, day) + person = _person(birth, disability_onset=date(year + 30, 1, 15)) + expected = _act_fra(birth) + assert i._fra_date(person) == expected + assert ( + i._fra_quarter(person) == expected.year * 4 + (expected.month - 1) // 3 + ) + + +def test_prior_period_is_capped_at_fra_for_status_and_requirement_helper(): + birth = date(1960, 1, 2) + common = dict( + birth_date=birth, + prior_disability_periods_provenance=OBSERVED, + current_disability_period_established=False, + current_disability_period_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + rib_entitlement_month=date(2028, 10, 1), + ) + overlong = i.Person( + **common, + prior_disability_periods=( + i.DisabilityPeriod(date(2026, 1, 15), date(2028, 9, 30)), + ), + ) + assert overlong.prior_disability_periods[0].end == date(2026, 12, 31) + month = date(2028, 10, 1) + years = history(overlong, month, {y: 4 for y in range(2016, 2026)}) + result = i.insured_status( + overlong, years, month, test=i.InsuredTest.CURRENTLY + ) + assert not result.currently.insured + assert result.currently.qc_count_lower == 5 + assert i.fully_insured_requirement(overlong, month) == 40 + + +@settings(max_examples=12, deadline=None) +@given( + counts=st.tuples(st.integers(0, 4), st.integers(0, 4)), + current=st.integers(0, 4), + kind=st.sampled_from([i.InsuredTest.FULLY, i.InsuredTest.CURRENTLY]), +) +def test_ongoing_period_completion_status_and_count_bounds_are_sound( + counts, current, kind +): + person, _, month = _endpoint_case() + years = history( + person, + month, + {2016: 4, 2017: 4, 2020: counts[0], 2021: counts[1], 2026: current}, + ) + concrete = [] + for ending in [date(2026, 3, 31), date(2026, 6, 30), date(2027, 12, 31)]: + value = i.insured_status( + replace( + person, + current_disability_period_end=ending, + current_disability_period_end_provenance=OBSERVED, + ), + years, + month, + test=kind, + ) + concrete.append(getattr(value, kind.value)) + try: + result = i.insured_status(person, years, month, test=kind) + except i.InsuredConfigurationUnsupported as refusal: + assert refusal.reason is i.InsuredUnsupportedReason.CURRENT_PERIOD_END + assert len({value.insured for value in concrete}) == 2 + return + decision = getattr(result, kind.value) + for value in concrete: + assert value.insured == decision.insured + assert ( + decision.qc_count_lower + <= value.qc_count_lower + <= decision.qc_count_upper + ) + assert ( + decision.fully_qc_count_lower + <= value.fully_qc_count_lower + <= decision.fully_qc_count_upper + ) + assert "current_disability_period_end" in result.unknown_facts + + +@settings(max_examples=15, deadline=None) +@given( + birth_year=st.integers(1938, 1960), + birth_month=st.integers(1, 12), + birth_day=st.sampled_from([1, 2]), + extra_years=st.integers(1, 5), +) +def test_every_supplied_prior_period_has_the_statutory_fra_cap( + birth_year, birth_month, birth_day, extra_years +): + from datetime import timedelta + + birth = date(birth_year, birth_month, birth_day) + fra = _act_fra(birth) + cap = fra.replace(day=1) - timedelta(days=1) + person = i.Person( + birth, + prior_disability_periods=( + i.DisabilityPeriod( + cap.replace(year=cap.year - 2, day=1), + cap.replace(year=cap.year + extra_years, day=1), + ), + ), + prior_disability_periods_provenance=OBSERVED, + ) + assert person.prior_disability_periods[0].end == cap + with pytest.raises(InvalidFamilyInput): + replace( + person, + prior_disability_periods=(i.DisabilityPeriod(fra, fra),), + ) + + +def test_unknown_current_period_after_fra_cannot_create_freeze_uncertainty(): + person = i.Person( + date(1960, 1, 2), + disability_onset=date(2028, 1, 15), + prior_disability_periods_provenance=OBSERVED, + current_disability_period_established=None, + current_disability_period_provenance=i.EarningsProvenance.UNKNOWN, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + month = date(2028, 10, 1) + assert i.fully_insured_requirement(person, month) == 40 + years = history(person, month, {y: 4 for y in range(2016, 2026)}) + result = i.insured_status(person, years, month, test=i.InsuredTest.FULLY) + assert result.fully.insured + assert result.unknown_facts == () + assert result.current_disability_period_start is None + + +@pytest.mark.parametrize("unknown", [False, True]) +def test_later_insurance_after_fra_cannot_establish_period_before_refusal( + unknown, +): + person = replace( + _fra_person(), + conditions=frozenset({i.CoverageCondition.RAILROAD_CREDITS}), + ) + month = date(2028, 10, 1) + years = history(person, month, {2027: 4, 2028: 4}) + if unknown: + years[2028] = i.CoverageYear(i.EarningsProvenance.UNKNOWN) + with pytest.raises(InvalidFamilyInput): + i.insured_status(person, years, month, test=i.InsuredTest.FULLY) + + +def test_period_calendar_rules_are_quoted_from_captured_authority(): + import xml.etree.ElementTree as ET + from pathlib import Path + + sources = Path(__file__).parent / "data/track_b/insured_status_sources" + act = (sources / "lii_usc_42_416_excerpts.txt").read_text() + cfr = "".join( + ET.fromstring( + (sources / "ecfr_20cfr404_321.xml").read_text() + ).itertext() + ) + for literal in [ + "no such period shall begin as to any individual after such individual attains retirement age", + "the month preceding the month in which the individual attains retirement age", + "the calendar years 2000 through 2004", + "the calendar years 2017 through 2021", + ]: + assert literal in act + for literal in [ + "Your period of disability may not begin after you have attained full retirement age", + "The month before the month in which you attain full retirement age", + "The month immediately preceding your termination month", + "the last month for which you received benefits", + ]: + assert literal in cfr + + +@settings(max_examples=15, deadline=None) +@given( + birth_year=st.integers(1938, 1960), + birth_month=st.integers(1, 12), + birth_day=st.sampled_from([1, 2]), + days_later=st.integers(0, 366), + unknown_prior=st.booleans(), +) +def test_known_establishment_at_or_after_fra_is_always_invalid( + birth_year, birth_month, birth_day, days_later, unknown_prior +): + from datetime import timedelta + + birth = date(birth_year, birth_month, birth_day) + onset = _act_fra(birth).replace(day=1) + timedelta(days=days_later) + with pytest.raises(InvalidFamilyInput): + i.Person( + birth, + disability_onset=onset, + current_disability_period_established=True, + current_disability_period_provenance=OBSERVED, + prior_disability_periods_provenance=( + i.EarningsProvenance.UNKNOWN if unknown_prior else OBSERVED + ), + ) + + +def test_fra_month_onset_cannot_begin_after_statutory_period_end(): + # A March1 birth attainsFRA onFebruary28. Act216(i)(2)(D)(i) + # ends any periodJanuary31, before thisFebruary15 onset. + with pytest.raises(InvalidFamilyInput): + person = _person(date(1960, 3, 1), disability_onset=date(2027, 2, 15)) + i.fully_insured_requirement(person, date(2027, 3, 1)) + + +def test_unknown_fra_month_onset_cannot_supply_freeze_uncertainty(): + person = i.Person( + date(1960, 3, 1), + disability_onset=date(2027, 2, 15), + prior_disability_periods_provenance=OBSERVED, + current_disability_period_established=None, + current_disability_period_provenance=i.EarningsProvenance.UNKNOWN, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + month = date(2027, 3, 1) + assert i.fully_insured_requirement(person, month) == 40 + result = i.insured_status( + person, + history(person, month, {y: 4 for y in range(2016, 2026)}), + month, + test=i.InsuredTest.FULLY, + ) + assert result.fully.insured + assert result.unknown_facts == () + assert result.current_disability_period_start is None + + +@settings(max_examples=15, deadline=None) +@example(year=2023, month=1, convention=False) +@given( + year=st.integers(2023, 2030), + month=st.integers(1, 12), + convention=st.booleans(), +) +def test_declared_period_end_provenance_roundtrip_and_invalid_combinations( + year, month, convention +): + import calendar + + person, _, _ = _endpoint_case() + ending = date(year, month, calendar.monthrange(year, month)[1]) + # Preserve the original twenty positional constructor slots. + original_positional = i.Person( + person.birth_date, + person.sex, + person.death_date, + person.disability_onset, + person.prior_disability_periods, + person.statutory_blindness, + person.conditions, + person.alien_worker, + person.ssn_assignment_date, + person.ssn_never_assigned, + person.rib_entitlement_month, + person.dib_entitlement_month, + person.prior_disability_periods_provenance, + person.prior_disability_periods_convention_id, + person.current_disability_period_established, + person.current_disability_period_provenance, + person.current_disability_period_convention_id, + person.sspa211_applies, + person.sspa211_provenance, + person.sspa211_convention_id, + ) + assert original_positional == person + provenance = ( + i.EarningsProvenance.CONVENTION_FILLED if convention else OBSERVED + ) + identifier = "invented-calendar-end" if convention else None + declared = replace( + person, + current_disability_period_end=ending, + current_disability_period_end_provenance=provenance, + current_disability_period_end_convention_id=identifier, + ) + assert declared.current_disability_period_end == ending + assert declared.current_disability_period_end_provenance is provenance + assert replace(declared) == declared + with pytest.raises(InvalidFamilyInput): + replace(declared, current_disability_period_end=None) + with pytest.raises(InvalidFamilyInput): + replace( + declared, + current_disability_period_end_provenance=( + i.EarningsProvenance.UNKNOWN + ), + current_disability_period_end_convention_id=None, + ) + with pytest.raises(InvalidFamilyInput): + replace(declared, current_disability_period_end=ending.replace(day=1)) diff --git a/tests/test_track_b_insured_status_fix_round_3_validation.py b/tests/test_track_b_insured_status_fix_round_3_validation.py new file mode 100644 index 000000000..01b59edc8 --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_3_validation.py @@ -0,0 +1,207 @@ +"""Statutory conformance: impossible UNKNOWN histories never count rows. + +Invented declarations only; no population, behavioral, or forecast claim. +""" + +from dataclasses import replace +from datetime import date +from fractions import Fraction + +import pytest +from hypothesis import example, given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as i +from populace_dynamics.track_b.gross_benefits import count_family_outcomes +from tests.test_track_b_insured_status import declared, history +from tests.test_track_b_insured_status_fix_round_2 import _person + + +def _impossible_person(onset=date(2000, 2, 2)): + return _person( + date(2000, 2, 2), + disability_onset=onset, + current_disability_period_established=True, + prior_disability_periods_provenance=i.EarningsProvenance.UNKNOWN, + ) + + +@pytest.mark.parametrize("onset", [date(2000, 2, 2), date(2020, 1, 15)]) +def test_impossible_establishment_with_unknown_prior_history_is_input_error( + onset, +): + person = _impossible_person(onset) + month = date(2029, 4, 1) + years = history(person, month, {2028: 4, 2029: 2}) + with pytest.raises(i.InvalidFamilyInput): + i.insured_status(person, years, month, test=i.InsuredTest.FULLY) + + +def test_impossible_establishment_creates_no_evaluator_denominator_row(): + person = _impossible_person() + month = date(2029, 4, 1) + rows = [] + with pytest.raises(i.InvalidFamilyInput): + rows.append( + i.evaluate_insured_status( + "impossible-current-period", + Fraction(2), + lambda: i.insured_status( + person, + history(person, month, {2028: 4, 2029: 2}), + month, + test=i.InsuredTest.FULLY, + ), + ) + ) + denominator = count_family_outcomes(rows) + assert denominator.rows == denominator.unsupported_rows == 0 + assert denominator.unsupported_weight == 0 + + +def test_impossible_unknown_history_validation_precedes_coverage_refusal(): + person = replace( + _impossible_person(), + conditions=(i.CoverageCondition.RAILROAD_CREDITS,), + ) + month = date(2029, 4, 1) + with pytest.raises(i.InvalidFamilyInput): + i.insured_status( + person, + history(person, month, {2028: 4, 2029: 2}), + month, + totalization_credits=("invented-foreign-credit",), + ) + + +@settings(max_examples=20, deadline=None) +@example( + earlier=4, + later=4, + unknown_early=True, + onset=date(2022, 1, 15), + old_history=True, +) +@given( + earlier=st.integers(0, 4), + later=st.integers(0, 4), + unknown_early=st.booleans(), + onset=st.sampled_from([date(2000, 2, 2), date(2022, 1, 15)]), + old_history=st.booleans(), +) +def test_invalid_unknown_declaration_has_no_valid_enumerated_filling( + earlier, later, unknown_early, onset, old_history +): + """One-way soundness against empty/one/two-period small fillings. + + Candidate periods must themselves begin disability insured without + earlier periods and last at least five months. UNKNOWN earnings are + filled by all five annual QC counts before checking the declarations. + Unproved feasibility may retain a refusal; no completeness is claimed. + """ + person = _impossible_person(onset) + month = date(2029, 4, 1) + counts = ( + {2019: earlier, 2020: later, 2028: 4} + if old_history + else {2028: earlier, 2029: later} + ) + years = history(person, month, counts) + if unknown_early: + years[2018] = declared(provenance=i.EarningsProvenance.UNKNOWN) + raised_invalid = False + try: + i.insured_status(person, years, month, test=i.InsuredTest.FULLY) + except i.InvalidFamilyInput: + raised_invalid = True + except i.InsuredConfigurationUnsupported: + pass + + valid = [] + observed = replace( + person, + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + ) + for count in range(5) if unknown_early else (0,): + filled = dict(years) + if unknown_early: + filled[2018] = declared(count) + credits = { + year: i._credits(year, row, False) for year, row in filled.items() + } + candidates = [] + for start, end in ( + (date(2020, 7, 1), date(2021, 1, 31)), + (date(2021, 4, 1), date(2021, 10, 31)), + ): + if ( + end < onset + and i._witness( + observed, + credits, + start, + None, + i.InsuredTest.DISABILITY, + onset=False, + )[0] + ): + candidates.append(i.DisabilityPeriod(start, end)) + fillings = [(), *((period,) for period in candidates)] + if len(candidates) == 2: + fillings.append(tuple(candidates)) + for periods in fillings: + try: + i.insured_status( + replace(observed, prior_disability_periods=periods), + filled, + month, + test=i.InsuredTest.FULLY, + ) + except i.InvalidFamilyInput: + valid.append(False) + except i.InsuredConfigurationUnsupported: + # A refusal is not a proof of a valid declaration. + continue + else: + valid.append(True) + if raised_invalid: + assert not any(valid) + if any(valid): + assert not raised_invalid + + +@settings(max_examples=12, deadline=None) +@given(shift=st.integers(0, 3), late=st.integers(2, 4)) +def test_valid_prior_freeze_filling_prevents_false_invalidity(shift, late): + """A long special period can rescue a current start invalid without it.""" + birth = date(1980 + shift, 2, 2) + month = date(2019 + shift, 4, 1) + person = _person( + birth, + disability_onset=date(2019 + shift, 1, 15), + current_disability_period_established=True, + prior_disability_periods_provenance=i.EarningsProvenance.UNKNOWN, + ) + years = history(person, month, {2001 + shift: 4, 2002 + shift: late}) + empty = replace( + person, + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + ) + with pytest.raises(i.InvalidFamilyInput): + i.insured_status(empty, years, month, test=i.InsuredTest.FULLY) + period = i.DisabilityPeriod( + date(2002 + shift, 4, 1), + date(2018 + shift, 9, 30), + special_insured=True, + ) + filled = i.insured_status( + replace(empty, prior_disability_periods=(period,)), + years, + month, + test=i.InsuredTest.FULLY, + ) + assert filled.fully.insured + try: + i.insured_status(person, years, month, test=i.InsuredTest.FULLY) + except i.InsuredConfigurationUnsupported as refusal: + assert refusal.reason is i.InsuredUnsupportedReason.UNKNOWN_PERIODS diff --git a/tests/test_track_b_insured_status_sources.py b/tests/test_track_b_insured_status_sources.py index 249f3ef4d..da6221628 100644 --- a/tests/test_track_b_insured_status_sources.py +++ b/tests/test_track_b_insured_status_sources.py @@ -189,6 +189,15 @@ def source_text(source_id): ], "poms_rs_00301_315": [ "The simplified method does not apply to disability claims.", + "Under the 1967 Amendments, use the simplified method if:", + "there are at least seven EYs; and", + "the NH is fully insured based on the number of QCs derived " + "under this method plus the number of QCs credited after 1950.", + "The NH is deemed to have one QC for each $400 of their total " + "wages before 1951.", + "If we find the NH is not insured or deemed to have one QC before " + "1951 under the simplified method, examine their record for the " + "1937-1950 period to determine the number of QCs posted.", ], "poms_rs_00301_320": [ "$400 or more paid in a calendar year-all four quarters are QCs;", @@ -246,6 +255,17 @@ def source_text(source_id): "However, we will count all the quarters in the prior period of " "disability established for you if by doing so you would be " "entitled to benefits or the amount of the benefit would be larger.", + "We do not count as part of the 13-quarter period any quarter " + "all or part of which is included in a period of disability " + "established for you, except that the first and last quarters " + "of the period of disability may be counted if they are QCs " + "(see § 404.146(d)).", + "The quarter is the first or the last quarter of this period; or", + "The period of disability is not taken into consideration " + "(see § 404.320(a)).", + "For purposes of paragraph (b) of this section, we may use the " + "following rules in crediting QCs based on your wages before " + "1951 instead of the rule in § 404.141(b)(1).", ], "ecfr_20cfr404_315": [ "The 5-month waiting period begins with a month in which you were " @@ -261,6 +281,9 @@ def source_text(source_id): "At least 5 consecutive months go by from the month in which " "your period of disability begins and before the month in which " "it would end.", + "You are insured for disability, as defined in § 404.130 in the " + "calendar quarter in which you became disabled, or in a later " + "calendar quarter in which you were disabled.", ], "ecfr_20cfr404_321": [ "Your period of disability begins on the day your disability " @@ -269,6 +292,17 @@ def source_text(source_id): "of disability will begin on the first day of the first calendar " "quarter after your disability began in which you become insured " "for disability.", + "Your period of disability may not begin after you have attained " + "full retirement age as defined in § 404.409.", + "Your period of disability ends with the close of whichever of " + "the following is the earliest", + "The month before the month in which you attain full retirement " + "age as defined in § 404.409.", + "The month immediately preceding your termination month " + "(§ 404.325); or", + "If you perform substantial gainful activity during the " + "reentitlement period described in § 404.1592a, the last month " + "for which you received benefits.", ], "lii_usc_42_413": [ "with such product, if not a multiple of $10, being rounded " @@ -277,6 +311,13 @@ def source_text(source_id): "of $10 in any other case.", "$10,800 in the case of a taxable year beginning after 1972 " "and before 1974", + "an individual shall be deemed to have one quarter of coverage " + "for each $400 of his total wages prior to 1951", + "except where such individual is not a fully insured individual " + "on the basis of the number of quarters of coverage so derived " + "plus the number of quarters of coverage derived from the wages " + "and self-employment income credited to such individual for " + "periods after 1950.", ], "lii_usc_42_414": [ "one quarter of coverage (whenever acquired) for each calendar " @@ -286,6 +327,33 @@ def source_text(source_id): "lii_usc_42_416": [ "on the first day of the first quarter thereafter in which he " "satisfies such requirements.", + "no such period shall begin as to any individual after such " + "individual attains retirement age (as defined in subsection (l)).", + "A period of disability shall end with the close of whichever " + "of the following months is the earlier:", + "the month preceding the month in which the individual attains " + "retirement age (as defined in subsection (l))", + "the termination month (as defined in section 423(a)(1) of this " + "title )", + "such period is of not less than five full calendar months' " + "duration or such individual was entitled to benefits under " + "section 423 of this title for one or more months in such period.", + "before January 1, 2000 , 65 years of age;", + "after December 31, 1999 , and before January 1, 2005 , 65 years " + "of age plus the number of months in the age increase factor", + "after December 31, 2004 , and before January 1, 2017 , 66 years " + "of age;", + "after December 31, 2016 , and before January 1, 2022 , 66 years " + "of age plus the number of months in the age increase factor", + "after December 31, 2021 , 67 years of age.", + "The term “ early retirement age ” means age 62 in the case of " + "an old-age, wife' s, or husband' s insurance benefit", + "the 5-year period consisting of the calendar years 2000 through " + "2004, the age increase factor shall be equal to two-twelfths of " + "the number of months in the period beginning with January 2000", + "the 5-year period consisting of the calendar years 2017 through " + "2021, the age increase factor shall be equal to two-twelfths of " + "the number of months in the period beginning with January 2017", ], "lii_usc_42_423": [ "not less than 20 quarters of coverage during the 40-quarter " diff --git a/tests/tier_counts.json b/tests/tier_counts.json index a40f167c6..a05ccb633 100644 --- a/tests/tier_counts.json +++ b/tests/tier_counts.json @@ -1,7 +1,7 @@ { "schema_version": 1, "counts": { - "unit": 19723, + "unit": 19826, "artifact": 4271, "integration_psid": 1471, "reproduction_legacy": 520, From 06f6e5776a36242dfdc7fbf5855a948978a6fc17 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sat, 31 Oct 2026 09:23:25 -0400 Subject: [PATCH 09/46] Keep insured-status proofs sound on every statutory route (#562 round 4) The round-3 review found three medium defects with one cause: each proof or bound used an ordinary-path premise where the law has an "or". This commit fixes the class: - A single predicate now decides whether a declared current period could be valid. It checks the ordinary, automatically detected and flagged routes before any fact-pattern InvalidFamilyInput. - An UNKNOWN administrative end now covers every quarter from the period's start through the query and FRA cap (416(i)(2)(D); 20 CFR 404.321(c)(3)). The FRA cap bounds the end and no longer removes the unknown fact. - A prior period may last one month, because Act 216(i)(2)(A) allows DIB entitlement in place of five months and 404.315(a)(4)(ii) waives the waiting period for ALS. - An ordinary failure no longer hides RS 00301.480's pre-1956 route. The design note gains a premise table for every fact-pattern input error, UNKNOWN collapse and bound. It also qualifies the Act 213(c) seven-year note, and the code now carries the us:oasdi-insured-pre1951-seven-elapsed-years marker. Tier counts add the 53 new unit tests to the three-way sum; the slot's recount replaces them. Subfleet job 20261031-082259-trackb-fix-insured-4 (gpt-6.1-sol) wrote this work. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 259 +++++++-- .../track_b_insured_status_mutations.json | 152 ++++- .../track_b_insured_status_rulespec_issue.md | 11 +- .../track_b/insured_status.py | 429 +++++++++----- tests/README-tiers.md | 4 +- ...test_track_b_insured_status_fix_round_2.py | 20 + ...ck_b_insured_status_fix_round_3_periods.py | 37 +- ...track_b_insured_status_fix_round_4_docs.py | 29 + ...ck_b_insured_status_fix_round_4_endings.py | 303 ++++++++++ ...ack_b_insured_status_fix_round_4_routes.py | 540 ++++++++++++++++++ ...ck_b_insured_status_period_declarations.py | 1 + tests/tier_counts.json | 2 +- 12 files changed, 1575 insertions(+), 212 deletions(-) create mode 100644 tests/test_track_b_insured_status_fix_round_4_docs.py create mode 100644 tests/test_track_b_insured_status_fix_round_4_endings.py create mode 100644 tests/test_track_b_insured_status_fix_round_4_routes.py diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index 407d65452..2644b725c 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -105,16 +105,20 @@ application and the statutory duration or DIB-entitlement alternative administrative facts. A known established period with no possible insured disabled quarter is invalid. Its start is derived from the supplied QC history, then its years are excluded like any other established period. -On the ordinary supported QC surface, this includes known current -establishment with fewer than six maximum feasible lifetime QCs even when -prior periods are UNKNOWN: 404.130(a) -requires fully insured status, and 404.110(b)(1) says, "You need at least -6 QCs but not more than 40 QCs to be fully insured." Excluding periods -cannot supply the missing credits. When declared QC facts prove this -contradiction, the input error precedes coverage refusals, including -foreign-credit, specialist, SSPA-applicability, and period-uncertainty -refusals. Other military, railroad, deemed, and transitional declarations -retain their specialist refusals; no alternate-credit regime is adjudicated. +Every fact-pattern establishment rejection uses one possibility check +across the ordinary route, automatically observable specialist routes, and declared +`CoverageCondition` routes. This check deliberately over-approximates: an +unresolved specialist possibility retains its named refusal. Only when all +routes are impossible can the rule raise `InvalidFamilyInput` before any +coverage refusal. On the ordinary supported QC surface, fewer than six +maximum feasible lifetime QCs proves impossibility: 404.130(a) requires +fully insured status, and 404.110(b)(1) says, "You need at least 6 QCs but +not more than 40 QCs to be fully insured." Period exclusions cannot supply +missing credits. That ordinary argument does not adjudicate deemed, +transitional, military, railroad, or other specialist routes. A flag or +observable specialist route that could validate the declaration prevents +that input error and preserves a refusal row. + When prior periods are UNKNOWN, favorable disregard of every period can still decide the Boolean status even if the current period's derived start is uncertain. `current_disability_period_start` is then `None`, and @@ -123,21 +127,29 @@ fact itself remains known. If the disregard treatment already qualifies at medical onset, onset is the certain start. Disregard is a permitted statutory treatment, not an assertion that a known period never existed. -Round 3 additionally proves when UNKNOWN prior history can only be empty -for establishment validation. The earliest nonempty period would need an -insured starting quarter without any earlier period (404.320(b)(2), -404.321(a)), on or after birth, before FRA, with time for five months before -its ending month (404.320(b)(4)), and an end before the current onset. -The scan uses the highest feasible QCs for every unknown year and a -permissive partial-month duration bound. If no quarter survives, validate -the current declaration against empty prior history at those highest QCs. -If even that world has no insured current start, raise `InvalidFamilyInput` -before any coverage refusal. An evaluator then creates no denominator row. -If a quarter survives, feasibility is unproved and a named refusal remains -possible. This is a sufficient invalidity proof, not a complete history -solver. For valid declarations the caller's UNKNOWN provenance, uncertain -start disclosure, and universal count envelope remain conservative; the -validation collapse does not invent an observed history. +UNKNOWN prior history can be proved empty for establishment validation only +when no earliest period could fit. Its insured starting quarter has no +earlier exclusions (404.320(b)(2); 404.321(a)); it is on or after birth, +before FRA, and before current onset. The feasibility scan admits a period +lasting only one month. Act 216(i)(2)(A) permits "not less than five full +calendar months' duration or such individual was entitled to benefits +under section 423 of this title for one or more months in such period." +The five-month phrase in 404.320(b)(4) therefore supplies no universal +minimum. Section 404.315(a)(4) also says "or no waiting period is required" +and lists recent prior entitlement or a period of disability and ALS as +waiting-period exceptions. The interface does not adjudicate those +administrative facts for an already declared period; it imposes no +five-month validation on current or supplied prior periods. + +The scan uses maximum feasible QCs for unknown years and does not try to +prove administrative feasibility. Any possible specialist starting route +also prevents an empty-history impossibility proof. If no quarter or route +survives, empty prior history is the only remaining case for current +establishment validation; only impossibility there permits an input error +and no denominator row. A surviving quarter establishes no actual history: +it merely prevents that error, preserving a named refusal when status is +unresolved. The caller's UNKNOWN provenance, uncertain start disclosure, +and universal count envelope remain conservative. An observation month never establishes a period's ending month. The statutory end is the earlier of a declared administrative end and the last @@ -145,18 +157,32 @@ day of the month before FRA (416(i)(2)(D); 404.321(c)); death also bounds the declared lifetime. `current_disability_period_end` optionally supplies that administrative ending date, on the last day of a month, with `current_disability_period_end_provenance` and, for a convention, -`current_disability_period_end_convention_id`. An omitted end stays unknown. +`current_disability_period_end_convention_id`. A default omitted end stays +unknown. These three optional fields append after the original twenty `Person` fields, preserving the existing positional facts as well as keyword calls. -For an ongoing period the rule compares an end in the observation month -with continuation through the statutory FRA limit. The observation quarter -may be credited as the last quarter in the former world but interior in -the latter (404.146(d); 404.120(b)). When a requested status differs, the -call refuses with `ongoing_disability_period_end_decides_status`; when it -agrees, counts contain both worlds and the unknown ending is disclosed. -At or beyond FRA the calendar supplies the actual cap rather than an -unknown ending. Established starts at or after FRA are invalid even if -prior history is UNKNOWN, and every supplied prior period is capped at +With an UNKNOWN ending, the rule evaluates every candidate end quarter from +the derived period's start through the last quarter allowed by the query +and FRA/death cap. It additionally considers continuation past the query +when the cap permits. Quarter representatives suffice because exclusions, +credited endpoints, and elapsed-year freezes change only at quarter/year +boundaries. It does not decide which candidates an administrative record +would establish. Continuous medical disability supplies no administrative +continuity: 404.321(c)(3) permits ending at "the last month for which you +received benefits" after substantial gainful activity, while Act +216(i)(2)(D) selects the earlier FRA or termination/no-benefit boundary. +Any candidate that changes a requested status retains +`ongoing_disability_period_end_decides_status`; a returned status agrees +across every candidate. Recent, prerequisite, annual-count, and DLI bounds +cover all those candidates. Reaching FRA supplies an upper bound on the +end, never its actual date; an UNKNOWN end stays in `unknown_facts` at +and after FRA, including when prior history is also UNKNOWN. Both missing +facts remain disclosed; UNKNOWN prior history uses the broader universal +envelopes rather than inventing a concrete current period for enumeration. +A supplied date retains the existing declaration semantics; +known ending provenance requires that date. + +Established starts at or after FRA are invalid even if prior history is UNKNOWN, and every supplied prior period is capped at the month before FRA. The standalone requirement helper shares these limits. A start in the FRA attainment month is also invalid because its mandatory end would precede its start, including a first-day birthday @@ -356,7 +382,7 @@ a subclass of the shared `FamilyConfigurationUnsupported`. | Unknown-year bounds decide a requested status differently | `unknown_earnings_years_decide_status` | | Unknown prior periods may change a requested status | `unknown_prior_disability_periods_decide_status` | | Unknown current establishment may change a requested status | `unknown_current_disability_period_decides_status` | -| Ongoing current period's observation-quarter ending versus continuation changes a requested status | `ongoing_disability_period_end_decides_status` | +| Any candidate end quarter for an UNKNOWN current ending changes a requested status | `ongoing_disability_period_end_decides_status` | | Unknown section 214(c) applicability may change a requested status | `sspa211_applicability_unknown` | | Standalone requirement helper needs coverage history to derive a declared current period start | `current_disability_period_requires_history` | | Ongoing established current period, known prior-period history, and a frozen-exit DLI horizon beyond query | `ongoing_disability_period_dli_horizon_unsupported` | @@ -433,6 +459,82 @@ counts all supported and refused rows and weights. Invalid declarations produce no outcome row. The seal is an API contract, not a security boundary against callers reaching private Python names or monkeypatching modules. +## Premises for rejection, unknown facts, and bounds + +A fact-pattern rejection means every concrete completion is impossible +under every potential route. A named refusal remains whenever an ordinary, +automatically observable specialist, or flagged specialist route could +validate the declaration. The common possibility predicate deliberately +admits extra candidates; absence of an ordinary witness alone is no proof +against a specialist route. This distinction also applies when the caller +requests a test other than disability: establishment is a fact of the +same declaration, not a conclusion restricted to the requested output. + +The tables inventory the fact-pattern input errors, every UNKNOWN collapse, +and the mathematical or computational bounds. Exact-type, enum, +provenance/value, convention-identifier, amount-domain, and representation +errors are schema checks and do not assert statutory impossibility. +Calendar and chronology restrictions that also form part of the declared +interface are identified explicitly below. They do not adjudicate an +undeclared application, service, recovery, or administrative ending. + +Capture shorthand refers only to files in +`tests/data/track_b/insured_status_sources/`: `B` is +`ecfr_20cfr404_subpart_b.xml`; `A216` is +`lii_usc_42_416_excerpts.txt`; `A213` and `A214` are the corresponding +`lii_usc_42_413_excerpts.txt` and `lii_usc_42_414_excerpts.txt`; +`C315`, `C320`, and `C321` are `ecfr_20cfr404_315.xml`, +`ecfr_20cfr404_320.xml`, and `ecfr_20cfr404_321.xml`; +`RS .nnn` means `poms_rs_00301_nnn.html`. Quoted text below is from those +captures. An interface premise is labeled as such rather than attributed +to a statutory sentence that does not state it. + +| ID and input-error premise | Captured text and alternative-route defense | +| --- | --- | +| I1. A period cannot end before its onset or derived insured start; a supplied administrative end requires a declared established current period and closes a calendar month. | A216(i)(2)(C) says a period begins on the disability day or "the first day of the first quarter thereafter"; (D) says it ends "with the close" of the earlier listed month. C321(a), (c) agree. Every specialist route must still have a nonempty chronological period; no ordinary witness alone decides whether a specialist supplied the insured start. The end/established association is also a declaration contract. | +| I2. Birth, disability onset, death, prior periods, entitlement, and SSN assignment must have consistent lifetime ordering. A query or coverage end cannot precede birth; medical onset or supplied entitlement cannot follow the query month; onset cannot follow death. | B404.102 defines "You or your" as "the worker whose insured status is being considered"; A216(i)(2)(A) requires a period "during which an individual was under a disability". Dates refer to that same living worker. This lifetime and observation-calendar contract is independent of the insured route. It permits onset later within the query month and the quarter of death rather than imposing a day-of-query restriction. | +| I3. An established period must start before its FRA-ending boundary, including no start in the FRA month; all supplied prior periods are capped at the preceding month end. | A216(i)(2)(B): "no such period shall begin ... after such individual attains retirement age"; (D)(i) ends at "the month preceding the month" of FRA. C321(a), (c)(1) say the same. A start after the mandatory month-end is impossible under both clauses, including first-day birthdays. The cap supplies no evidence against an earlier UNKNOWN end. | +| I4. Supplied prior periods precede the current event/onset and query, do not overlap calendar quarters, and stay within the lifetime. | B404.130(f) refers to "a prior period of disability established for you". C321 gives chronological beginning and ending rules. Nonoverlapping quarter intervals are the declared history representation; specialist credits cannot change what "prior" or a unique represented quarter means. A known overlap is invalid, but overlap between a supplied prior period and a start derived in one UNKNOWN-earnings representative cannot disprove other fillings with a later nonoverlapping start. UNKNOWN history is not treated as supplied empty history. | +| I5. A supplied `special_insured` prior period begins before the age-31 attainment quarter. | B404.130(d)(1): a prior period "began before age 31" and the worker "were only insured under paragraph (c)"; (c)(1) requires age 31 not yet attained. A216(i)(3)(B)(iii) expressly uses "before the quarter" of age 31. The flag declares this particular adjudicated young-worker route, not every possible special credit regime. | +| I6. Conflicting SSPA applicability declarations, both never-assigned and an assigned SSN, or assignment before birth are invalid. | RS .102 B.1 distinguishes "first assigned on or after January 1, 2004" from an earlier first assignment; B.3 says "or if they have not yet been assigned an SSN based on their true identity". Mutually contradictory declarations cannot be repaired by a visa/work-authorization route. Meeting the additional requirement is distinct from exemption. | +| I7. Explicit quarterly QCs or positive quarterly wages cannot occur before birth, after the query/coverage-end quarter, or after the death quarter. Every required coverage year is declared exactly once through the earliest query, exit, or death year. | A213(a)(2)(B)(i), (v): "no quarter after the quarter in which an individual dies" and "no quarter shall be counted ... prior to the beginning of such quarter"; B404.146(a)-(b) agree. Birth and supplied-record exit caps, complete years, and no implicit zeros are interface premises. Annual counts are capped rather than dated after exit. Specialist earned-basis or additional-credit declarations remain refusals and do not reinterpret an explicit ordinary covered-quarter declaration. | +| I8. A declared current establishment with no possible insured start is invalid only after the shared possibility check excludes every route and every feasible prior/earnings filling. | C320(b)(2) requires insured disability "in the calendar quarter in which you became disabled, or in a later calendar quarter"; C321(a) chooses the first such quarter. B404.130(a) says "four different rules"; RS .480 supplies an additional historical test with "at least 20 quarters of coverage" and every qualifying 1951 quarter. Flagged routes and automatically detected alternatives defeat an ordinary-only impossibility proof. An UNKNOWN-credit representative that places the first insured start after a declared end does not exclude a different credit filling with an earlier valid start; even upper-credit construction failure is not proof if an ordinary insured candidate remains possible. In particular, its derived start may overlap a prior quarter while a lower-credit filling starts later without overlap. | +| I9. Fewer than six maximum feasible ordinary lifetime QCs proves current establishment impossible only when all specialist possibilities have already been excluded. | B404.110(b)(1): "You need at least 6 QCs but not more than 40 QCs"; B404.130(a): "you must be fully insured". B404.110(a) separately names deemed veteran/nonprofit routes, and RS .131/.350 cover other credits. Those alternatives prevent applying the ordinary six-QC input-error proof to a potentially valid specialist declaration. A record composed entirely of direct final QC declarations (`qc_count` or `qc_quarters`) and UNKNOWN years already fixes or bounds all admissible QCs, including RR credits, so the RR flag cannot add quarters beyond that envelope. This is the direct-credit input contract, not a claim that ordinary RSDI credits always exhaust freeze credits: RS .131 expressly allows credits "not creditable for other" purposes. If earnings allocation or that final-credit declaration is unresolved, the RR route remains possible; RS .230 and .350 supply annual and historical RR credit rules. Period exclusions alone cannot add ordinary QCs. | +| I10. The supported calendar, mandatory historical sex, and explicit establishment declaration must be supplied: birth years 1870–9900, query years through 9990, sex for births before January 2, 1913, and establishment provenance whenever onset is present. | These are interface-domain requirements. B404.110(b)(2) and .132 apply different historical male/female endpoints; B404.110(c) excludes only a period "we established for you". Missing facts are not inferred. Calendar limits reserve space for date arithmetic and assert no legal incapacity outside the implementation domain; alternative credit routes cannot supply missing declared facts. | + +| ID and UNKNOWN collapse | Captured text and alternative-route defense | +| --- | --- | +| U1. UNKNOWN prior history can collapse to empty solely for impossibility validation when no earliest prior period could start insured, on/after birth, before current onset and the FRA end. | C320(b)(2) and C321(a) require an insured beginning without a still-earlier period. A216(i)(2)(A) permits "five full calendar months' duration or" DIB entitlement "for one or more months". The scan therefore admits a one-month period and maximum feasible earnings. Any possible ordinary or specialist starting route stops the proof. It establishes no observed empty-history fact. | +| U2. UNKNOWN current establishment needs no new-period alternative if there is no medical onset or onset is at/after the statutory latest starting month. | A216(i)(2)(A)-(D) and C321 prohibit a period without disability or a nonempty pre-FRA interval. This removes an impossible new-period alternative only; it does not remove UNKNOWN prior history or an existing period's UNKNOWN administrative end. | +| U3. With unknown prior/current periods, true ordinary status under favorable all-period disregard decides true. | C320(a): "If benefits ... would be denied or reduced because of a period of disability, the period of disability will not be taken into consideration." B404.130(f) also permits counting all prior quarters if favorable. RS .120 requires all periods used or all disregarded; selective exclusions are not assumed. Specialist credit regimes are refused first. | +| U4. With unknown periods, fewer than six maximum feasible QCs decides false only on the ordinary route after specialist possibilities are excluded. | B404.110(b)(1) and B404.130(a) supply the six-QC prerequisite. U3's disregard cannot manufacture credits. Deemed, transitional, foreign, military/railroad, and automatically revealed historical alternatives retain named refusals instead of using this ordinary collapse. | +| U5. UNKNOWN earnings decide a requested Boolean only if all lower/upper ordinary earnings witnesses agree, under the permitted fixed-period/all-period treatments; an uncertain established start refuses. | B404.143 credits one QC for each increment, maximum four; B404.130 and .146 supply assignment/exclusion rules. Adding ordinary QCs cannot invalidate a fixed treatment. A derived start cannot be silently held fixed when the completion changes it. If a lower or upper representative cannot construct the declared period, including a derived overlap with a supplied prior period, but another UNKNOWN-credit filling can, the public result is `unknown_earnings_years_decide_status`, not an input error. Specialist possibilities and administrative-end candidates are considered separately, so the endpoint argument is never used to exclude them. | +| U6. UNKNOWN administrative end decides a status only when every end-quarter candidate from start through query/cap, plus permitted continuation, agrees. | A216(i)(2)(D) uses "whichever ... is the earlier"; C321(c)(3) includes "the last month for which you received benefits" after substantial gainful activity. Medical continuity cannot exclude early ends. FRA/death caps limit the latest candidate and do not turn the unknown into a fact. Both ending and prior-history unknown facts remain disclosed when both are missing; UNKNOWN prior history uses the universal envelopes rather than inventing a derived current period to enumerate. An actual supplied end keeps its declared-date semantics; known ending provenance requires an ending date. | +| U7. UNKNOWN SSPA applicability preserves an ordinary QC-only false status, but never a QC-only true status. | RS .102 B.2 says the worker "must meet one of the following additional requirements" and may fail "even if" the QC requirement is met. Applicability can remove ordinary insurance and cannot supply missing QCs. Known applicability retains adjudication refusal; any separate specialist path is refused first. | +| U8. With UNKNOWN prior history, a known current period's start is certain onset only if the lower-credit favorable-disregard witness already insures at onset; otherwise the start stays unknown. | A216(i)(2)(C) and C321(a) make insured onset the earliest legal start. C320(a)'s disregard permits that witness, and no route can move this period before medical onset. Other potentially valid histories prevent an impossibility error but do not fabricate a start. | + +| ID and bound | Captured text and alternative-route defense | +| --- | --- | +| B1. UNKNOWN annual ordinary QCs range from zero through four, reduced by assignable birth/query/death/exit quarters. Exact annual amounts are monotone in earnings; every calendar year stays in 0–4. | B404.143: "we cannot credit you with more than four QCs for any calendar year"; A213(a)(2)(B)(vi) prohibits duplicate calendar-quarter QCs; B404.146 excludes unbegun/death quarters. Birth/exit are supplied-record premises. Additional-credit regimes retain refusal and cannot escape this bound through an ordinary result. | +| B2. Ordinary fully insured requirements lie in 6–40 and exclude only established disability years. Every elapsed-year endpoint uses its relevant candidate year and the historical sex/cohort rule. | B404.110(b)(1), (b)(2), (c), .132; A214(a) says "not counting ... any year any part of which was included in a period of disability". Medical onset without establishment cannot freeze years. Deemed/transitional alternatives are refused before using the ordinary requirement as universal. | +| B3. A simplified-pre1951 possibility uses the smallest known freeze requirement, or six for unresolved establishment/history, and maximum post1950 ordinary credits without exclusions. UNKNOWN pre1951 raw wages remain potentially decisive. | A213(c) grants "one quarter of coverage for each $400" subject to resulting fully insured status; B404.110(c)-(d); RS .315 B.1-B.2 record alternate historical/application conditions. This is an over-approximation for refusal, not a computed deemed-credit answer. A favorable ordinary witness with a higher requirement cannot narrow it. | +| B4. An alternate-pre1956 possibility uses maximum feasible QCs and any eligible 1952Q3–1955Q4 quarter with at least 20 total QCs and every preceding 1951-onward quarter credited, minimum six. | RS .480 A requires "at least 20 quarters of coverage" and "all quarters beginning with 03/51 ... are QCs" with "at least six"; B.1 gives first freeze day 07/01/52 and last 12/31/55. Unmodeled application restrictions can only remove candidates, so they cannot justify an input error. Flagged specialist routes also preserve possibility. | +| B5. Universal recent, fully-prerequisite, and annual count envelopes use zero through maximum feasible ordinary lifetime/year QCs whenever unknown periods/earnings can switch witnesses. | A213(a)(2)(B)(vi) prohibits double credit; B404.146(d) excludes interiors unless disregarded. Every concrete ordinary assignment is a subset of feasible unique lifetime quarters. The envelope permits every witness, even when adding QCs switches to a lower-count witness. Specialist possibilities remain refusals. | +| B6. With known earnings and an UNKNOWN ending, returned count bounds include all end-candidate counts; with entirely known facts they remain exact. | B404.120(b), .130(f), .146(d) distinguish credited endpoints and excluded interiors. All candidate quarters are enumerated, including early endpoints and capped-FRA candidates; extrema therefore cover each completion. No monotonic endpoint-count premise is used. | +| B7. DLI lies through query without frozen exit, or through the pre-FRA-quarter/death horizon with frozen coverage; `None` is the bottom bound. A future exit cannot remove query censoring. | RS .148 defines DLI as "the last day in the last quarter" in which status is met and limits the search relative to FRA. B404.146(b) caps credits after death; A216(i)(2)(B) caps new periods. Future undeclared work is not assumed zero. Specialist routes are refused before this ordinary DLI calculation. | +| B8. For a nonblind ordinary worker with no prior period, no DLI can lie more than 39 quarters after the last credited quarter. | B404.130(b)(2) requires "at least 20 QCs in the 40-quarter period ... ending with that quarter". After 39 later quarters no original QC remains. Blindness and prior-period special/exclusion routes disable this search shortcut; flagged or observable specialist routes refuse. | +| B9. With unknown periods the disregard DLI is a lower bound and the permitted query/FRA/death horizon is the upper bound; unknown SSPA applicability reduces any positive DLI lower bound to `None`. | C320(a) permits favorable disregard; B404.130(f) permits counting all prior-period quarters; RS .102 B.2 imposes an additional requirement. The bound does not infer a particular recovery or history. Exemption can recover the ordinary upper witness but cannot exceed the calendar horizon. | +| B10. UNKNOWN-ending DLI bounds include every end candidate. With an unresolved ongoing end, known prior history, and frozen-exit future horizon beyond query, the named DLI-horizon refusal remains. | C321(c)'s alternative endings and RS .148's last qualifying quarter permit different historical DLI witnesses. The candidate extrema bound all declared endings; no recovery beyond the query is inferred. Refusal covers the unobserved future administrative fact. | +| B11. At most 4,096 combinations of disability endpoint assignments are searched exactly. | B404.143(b) and RS .230 permit favorable assignment; B404.130(f) makes endpoint credits decisive. The limit is computational coverage, not a statutory impossibility bound: exceeding it returns `disability_boundary_assignments_unsupported`, never a false status or input error. | +| B12. Ordinary counted windows have 13 quarters for current insurance and 40 for ordinary disability; young/subsequent special windows require half their elapsed quarters after dropping an odd remainder, with a six-QC minimum and 20/40 ceiling. | B404.120(a) says "13-quarter period"; .130(b) says "20 QCs in the 40-quarter period"; .130(c)-(d) and A216(i)(3)(B) supply the half-quarter, odd-remainder, and 6/12 alternatives. Blindness uses only the fully insured prerequisite, and pre1956/flagged specialist paths retain refusal rather than being forced through an ordinary window. | +| B13. Indexed annual QC amounts are at least the prior year's statutory increment and the rounded indexed 1978 amount, with nearest-$10 rounding and $5 ties upward. | A213(d)(2) chooses "the larger of" the prior increment and indexed amount, rounded to "the next higher multiple of $10" at a $5 tie. This exact parameter calculation has no disability or specialist alternative; input-domain checks require positive NAWI and a statutory prior increment. | + +The round-4 adversarial audit revisits each row's alternatives in the final +report. The three new source-mandated counterexamples are short +DIB-entitled periods (U1), early administrative endings including FRA +(U6/B6/B10), and the alternate pre1956 establishment route (I8/I9/B4). +None is an unresolved statutory reading. + ## Executed invariants The test modules named below provide example assertions and Hypothesis @@ -497,7 +599,7 @@ Round 3 adds these invariants: | FRA date and quarter equal an independent implementation of Act 216(l), including both step-up bands and first/second-day birthdays. | `test_fra_date_and_quarter_match_independent_act_calendar` | | Every supplied prior period ends no later than the month before FRA. | `test_every_supplied_prior_period_has_the_statutory_fra_cap` | | A known current establishment at or after FRA is invalid for observed and UNKNOWN prior histories. | `test_known_establishment_at_or_after_fra_is_always_invalid` | -| A returned ongoing-period status agrees with concrete ending-quarter and continuing completions, and the returned recent/fully QC counts contain their counts; otherwise the named ending refusal applies. | `test_ongoing_period_completion_status_and_count_bounds_are_sound` | +| A returned ongoing-period status agrees with concrete ending-quarter and continuing completions, and the returned recent/fully QC counts contain their counts; round 4 extends this to every candidate from the start through the cap, retaining UNKNOWN at FRA. | `test_ongoing_period_completion_status_and_count_bounds_are_sound` | | Proving an UNKNOWN declaration invalid implies all enumerated valid-calendar, insured-start empty/one/two-period and annual-QC fillings are invalid; a valid filling prevents that error. | `test_invalid_unknown_declaration_has_no_valid_enumerated_filling` | | A valid long prior special period can rescue current establishment; UNKNOWN history must retain that possibility even when observed empty history would be invalid. | `test_valid_prior_freeze_filling_prevents_false_invalidity` | | Declared ending facts and provenance round-trip, inconsistent values/provenance/convention identifiers are invalid, and the original twenty positional Person fields keep their meaning. | `test_declared_period_end_provenance_roundtrip_and_invalid_combinations` | @@ -506,9 +608,56 @@ Round 3 adds these invariants: | Automatic pre1951 detection bounds the lower fully insured requirement from a known disability freeze at exact aggregate-dollar boundaries, even when the ordinary witness selects a higher requirement. | `test_pre1951_refusal_bounds_every_known_freeze_requirement` | | Automatic pre1956 alternative refusals require at least 20 possible QCs and the continuous qualifying 1951 window. | `test_pre1956_refusal_requires_twenty_qcs_and_the_continuous_window` | +Round 4 extends those invariants across every statutory alternative: + +| Invariant | Hypothesis test | +| --- | --- | +| If an UNKNOWN administrative ending returns a requested status, every declared ending-quarter completion from the period's start through the query/cap has that status. Recent, fully-prerequisite, and annual QC ranges contain every completion, including earlier endings and FRA queries; ending uncertainty remains disclosed. | `test_unknown_end_status_and_every_count_cover_all_quarter_completions` | +| Every concrete administrative-ending DLI lies within the returned UNKNOWN-ending DLI range. | `test_unknown_end_dli_contains_every_administrative_end_completion` | +| An `InvalidFamilyInput` establishment conclusion excludes every enumerated ordinary, one-month/short-DIB-entitled, alternate-pre1956, and flagged-specialist filling; every valid refusal retains its evaluator row and weight. | `test_invalid_declaration_has_no_short_or_specialist_valid_filling` | +| An alternate-pre1956 earliest prior period prevents UNKNOWN prior history from being proved empty, even when the later current onset itself is after 1955. | `test_unknown_prior_history_preserves_pre1956_alternate_prior_start` | +| A valid UNKNOWN-earnings completion with its insured start on/before the declared period end prevents an input error, even if another representative starts after the end; uncertainty retains a refusal and denominator row. | `test_possible_unknown_earnings_filling_prevents_declared_end_input_error` | +| A valid lower-credit completion whose derived current start does not overlap a supplied prior period prevents an input error, even if the upper-credit representative overlaps its ending quarter; uncertainty retains a refusal and denominator row. | `test_possible_lower_earnings_filling_prevents_upper_overlap_input_error` | + +Round-4 example/evaluator regressions separately reproduce the reviewer's +short-DIB prior period, early end and FRA-end cases, and automatic +pre1956 establishment for every requested test with UNKNOWN prior history +and UNKNOWN establishment variants. The flagged RR regression +`test_unresolved_railroad_compensation_retains_independent_flagged_route` +pins unresolved additional credits, while earlier assertions retain the +explicit final-direct-QC envelope. The round-3 two-point completion +property is extended to the wider candidate range; its earlier concrete +completion assertions are preserved. + +An additional invented completion case has birth February 2, 2000, +blindness onset January 15, 2022, declared establishment and a March 31, +2022 ending, queried January 2023. There are two QCs in 2020, three in +2021, one in 2023, and UNKNOWN 2022 credits. Zero QCs in 2022 first insure +the worker in 2023, after the declared end; each concrete count from one +through four can instead start the period at January 15, 2022. The +inconsistent lower representative therefore cannot prove the UNKNOWN +declaration invalid. The rule retains `unknown_earnings_years_decide_status` +and one evaluator row, as pinned by +`test_unknown_earnings_can_place_insured_start_before_declared_end` and +`test_unknown_earnings_before_declared_end_retains_denominator_row`. + +A neighboring invented case has a woman born February 2, 1910, a supplied +July 15, 1952–January 31, 1972 prior period, current onset February 15, +1972, and query January 1973. Twenty historical QCs and all six continuous +1951Q1–1952Q2 QCs support the prior period under the alternate pre1956 +route. Nineteen recent QCs in 1967–1971 and one in 1973, with UNKNOWN +1972 credits, give a valid January 1, 1973 current start when 1972 has +zero QCs. Positive 1972 fillings can instead derive a start in the prior +period's ending quarter and violate the quarter-overlap representation. +That invalid upper representative does not invalidate the UNKNOWN +declaration; `test_unknown_earnings_can_avoid_derived_prior_quarter_overlap` +and the lower-filling property retain the named earnings refusal and row. + The reviewer regressions additionally pin the 2026 blind-onset endpoint case (five continuing QCs versus six if the period ends in the event -quarter), the 1960 birth FRA case (five QCs and false in October 2028), +quarter), and the 1960 birth FRA case (UNKNOWN-ending count range [2, 5] +in October 2028, with five QCs for the concrete FRA-cap ending and false +status for every candidate). They also pin post-FRA establishment errors, invalid-before-refusal and zero evaluator rows, and Sam's seven elapsed-year prerequisite. Source literal tests retain the statutory end, duration, cohort, and simplified-credit clauses. @@ -654,19 +803,33 @@ For simplified pre1951 credits, Act 213(c) says an individual "shall be deemed to have one quarter of coverage for each $400 of his total wages prior to 1951", subject to becoming fully insured with the resulting credits plus post1950 credits. It states no seven-elapsed-year minimum. -RS .315 instead says "Under the 1967 Amendments, use the simplified method -if:" and "there are at least seven EYs; and"; CFR 404.110(d) uses permissive -"we may use the following rules" and also has the seven-year condition. -The evaluator refuses a potentially decisive aggregate even below seven -elapsed years. That avoids silently denying the statutory path while -filing, retroactivity, and section 227 facts remain absent. Both dates in +Historical amendments explain part of the apparent difference. RS .315 +B.1.a says, "Under the 1967 Amendments, use the simplified method if:" +and requires at least seven elapsed years. B.1.b then states, "The 1990 +Amendments eliminated the seven EY test." Its effective-date section +requires applications effectively filed in June 1992 or later and excludes +special age-72 or transitional insurance in the filing month. Section +404.110(d)(1)(ii) likewise supplies a June-1992-or-later application +exception, conditioned on no section 227 entitlement in the application +month; paragraph (d)(1)(i) retains the seven-year rule. + +The evaluator keeps the below-seven named refusal because filing, +retroactivity, and section 227 facts remain absent. It does not claim an +unqualified conflict between current statute and all regulatory/POMS +routes. Both dates in `test_potential_simplified_method_refuses_unresolved_seven_ey_applicability` pin this refusal: an invented woman born February 2, 1895, with $2,400 in 1940Q1 has one ordinary QC, six deemed QCs, and a six-QC prerequisite at -February 1968. A strict seven-year eligibility reading would return false; -the broader statutory reading could return true. If an otherwise payable -invented monthly benefit were $1,000, that would be $0 versus $1,000; -this module computes neither payment and retains the named refusal. +February 1968. Applying only the seven-year route would return false; +a favorable applicable alternative could return true. The facts supplied +do not establish that historical entitlement. Conditional on an otherwise +payable invented $1,000 monthly benefit, those answers differ by $0 versus +$1,000; this module computes neither payment. + +Short DIB-entitled periods, earlier administrative endings, and the +alternate pre1956 test are captured source requirements and missing +administrative facts. They introduce no competing reading or additional +question for Max. Mutation checks are recorded in [`track_b_insured_status_mutations.json`](track_b_insured_status_mutations.json). diff --git a/docs/design/track_b_insured_status_mutations.json b/docs/design/track_b_insured_status_mutations.json index 35be1dc76..51c7048ea 100644 --- a/docs/design/track_b_insured_status_mutations.json +++ b/docs/design/track_b_insured_status_mutations.json @@ -1697,7 +1697,7 @@ "log": "scratch/review/mutation-r3-validation-restored-baseline.log" }, "round_3_final_source_sha256": "7a99028e7e227e3311e3f0b547e25260a4ce3c5b24bdda41a7ae53212744c6c9", - "round_3_note": "Actual mutation execution records are retained. Narrow restoration preserved disjoint concurrent edits. Each implementation mutation was caught; Sam is a documentary mutation because the existing arithmetic was correct. Final scoped gates are recorded in scratch/review/fix-round-3-report.md.", + "round_3_note": "Actual mutation execution records are retained. Narrow restoration preserved disjoint concurrent edits. Each implementation mutation was caught; Sam is a documentary mutation because the existing arithmetic was correct. The round-3 report was not kept; its scratch path is not a retained evidence artifact.", "round_3_source_transition": { "previous_final_source_sha256": "a4f06ba3a5883f6b8e96a7887063499bc8e49512870f986c74355106d23b1b26", "final_source_sha256": "a0d10a7fb495ecc48ee76d2d4b77eb4d9108db311246ec498604487ef2c3c37c", @@ -1718,5 +1718,153 @@ "restoration_exact": true, "evidence": "scratch/review/round3-exact-head-replay.json", "label": "Post-fix baseline replay; initial failing-first chronology remains in scratch notes." - } + }, + "round_4_mutations": [ + { + "name": "restore_five_month_minimum", + "before": " possible_prior = replace(\n", + "after": " if start.year * 12 + start.month - 1 + 5 > latest_end.year * 12 + latest_end.month - 1: break\n possible_prior = replace(\n", + "failed_tests": [ + "tests/test_track_b_insured_status_fix_round_4_routes.py::test_short_dib_entitled_prior_period_keeps_unknown_history_refusal" + ], + "command": "POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/round4-epuf POPULACE_DYNAMICS_PSID_DIR=/nonexistent/round4-psid PYTHONPATH=$PWD/src:$PWD OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\np=Path('src/populace_dynamics/track_b/insured_status.py')\ns=p.read_text()\nbefore=hashlib.sha256(p.read_bytes()).hexdigest()\nold=\" possible_prior = replace(\\n\"\nreplacement=\" if start.year * 12 + start.month - 1 + 5 > latest_end.year * 12 + latest_end.month - 1: break\\n possible_prior = replace(\\n\"\nassert s.count(old)==1\nexec(compile(s.replace(old,replacement), '', 'exec'), i.__dict__)\nresult=pytest.main([\"-q\",\"-p\",\"no:xdist\",\"-p\",\"no:cacheprovider\",\"tests/test_track_b_insured_status_fix_round_4_routes.py::test_short_dib_entitled_prior_period_keeps_unknown_history_refusal\",\"--tb=short\"])\nafter=hashlib.sha256(p.read_bytes()).hexdigest()\nprint('MUTATION',\"five_month_minimum\",'pytest_exit',result,'source_sha256',before,'unchanged',before==after)\nassert before==after\nraise SystemExit(result)\nPY", + "summary": "1 failed in 19.64s; restored five-month premise incorrectly raises InvalidFamilyInput for a valid short DIB-entitled prior filling.", + "source_hash": "042488e8b685ee4a5d4a608073762439e781242d416c587152628eb8b656df16", + "source_hash_unchanged_after_run": true, + "isolated": true, + "restored": true, + "restoration": "The mutated source was executed only in the isolated Python process's canonical module namespace. No working-tree source write occurred; process exit discarded the mutant. Both before/after file SHA-256 values matched.", + "source_transition_note": "This hash identifies the implementation at this execution. Later restored controls include the UNKNOWN-prior integration guard, continued missing-end disclosure, and the additional lower/upper valid-fillings handling; those edits are not represented by this earlier execution hash." + }, + { + "name": "disable_specialist_establishment_escape", + "before": " if _specialist_establishment_possible(\n person, years, credits, month, exit_month\n ):\n", + "after": " if False and _specialist_establishment_possible(\n person, years, credits, month, exit_month\n ):\n", + "failed_tests": [ + "tests/test_track_b_insured_status_fix_round_4_routes.py::test_pre1956_established_period_retains_automatic_specialist_refusal", + "tests/test_track_b_insured_status_fix_round_4_routes.py::test_unresolved_railroad_compensation_retains_independent_flagged_route" + ], + "command": "POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/round4-epuf POPULACE_DYNAMICS_PSID_DIR=/nonexistent/round4-psid PYTHONPATH=$PWD/src:$PWD OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\np=Path('src/populace_dynamics/track_b/insured_status.py')\ns=p.read_text()\nbefore=hashlib.sha256(p.read_bytes()).hexdigest()\nold=\" if _specialist_establishment_possible(\\n person, years, credits, month, exit_month\\n ):\\n\"\nreplacement=\" if False and _specialist_establishment_possible(\\n person, years, credits, month, exit_month\\n ):\\n\"\nassert s.count(old)==1\nexec(compile(s.replace(old,replacement), '', 'exec'), i.__dict__)\nresult=pytest.main([\"-q\",\"-p\",\"no:xdist\",\"-p\",\"no:cacheprovider\",\"tests/test_track_b_insured_status_fix_round_4_routes.py::test_pre1956_established_period_retains_automatic_specialist_refusal\",\"tests/test_track_b_insured_status_fix_round_4_routes.py::test_unresolved_railroad_compensation_retains_independent_flagged_route\",\"--tb=short\"])\nafter=hashlib.sha256(p.read_bytes()).hexdigest()\nprint('MUTATION',\"no_specialist_escape\",'pytest_exit',result,'source_sha256',before,'unchanged',before==after)\nassert before==after\nraise SystemExit(result)\nPY", + "summary": "2 failed in 21.50s; automatic pre1956 and independent unresolved-RR possibilities incorrectly become InvalidFamilyInput.", + "source_hash": "042488e8b685ee4a5d4a608073762439e781242d416c587152628eb8b656df16", + "source_hash_unchanged_after_run": true, + "isolated": true, + "restored": true, + "restoration": "The mutated source was executed only in the isolated Python process's canonical module namespace. No working-tree source write occurred; process exit discarded the mutant. Both before/after file SHA-256 values matched.", + "source_transition_note": "This hash identifies the implementation at this execution. Later restored controls include the UNKNOWN-prior integration guard, continued missing-end disclosure, and the additional lower/upper valid-fillings handling; those edits are not represented by this earlier execution hash." + }, + { + "name": "disable_historic_prior_pre1956_escape", + "before": " if _pre1956_alternate_possible(\n possible_prior, credits, start, exit_month\n ):\n", + "after": " if False and _pre1956_alternate_possible(\n possible_prior, credits, start, exit_month\n ):\n", + "failed_tests": [ + "tests/test_track_b_insured_status_fix_round_4_routes.py::test_unknown_prior_history_preserves_pre1956_alternate_prior_start" + ], + "command": "POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/round4-epuf POPULACE_DYNAMICS_PSID_DIR=/nonexistent/round4-psid PYTHONPATH=$PWD/src:$PWD OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\np=Path('src/populace_dynamics/track_b/insured_status.py')\ns=p.read_text()\nbefore=hashlib.sha256(p.read_bytes()).hexdigest()\nold=\" if _pre1956_alternate_possible(\\n possible_prior, credits, start, exit_month\\n ):\\n\"\nreplacement=\" if False and _pre1956_alternate_possible(\\n possible_prior, credits, start, exit_month\\n ):\\n\"\nassert s.count(old)==1\nexec(compile(s.replace(old,replacement), '', 'exec'), i.__dict__)\nresult=pytest.main([\"-q\",\"-p\",\"no:xdist\",\"-p\",\"no:cacheprovider\",\"tests/test_track_b_insured_status_fix_round_4_routes.py::test_unknown_prior_history_preserves_pre1956_alternate_prior_start\",\"--tb=short\"])\nafter=hashlib.sha256(p.read_bytes()).hexdigest()\nprint('MUTATION',\"no_historic_prior_alternate\",'pytest_exit',result,'source_sha256',before,'unchanged',before==after)\nassert before==after\nraise SystemExit(result)\nPY", + "summary": "1 failed in 25.63s at explicit minimized example ending_year=1959, extra=0; historic specialist prior cannot be excluded by current-onset ordinary validation.", + "source_hash": "042488e8b685ee4a5d4a608073762439e781242d416c587152628eb8b656df16", + "source_hash_unchanged_after_run": true, + "isolated": true, + "restored": true, + "restoration": "The mutated source was executed only in the isolated Python process's canonical module namespace. No working-tree source write occurred; process exit discarded the mutant. Both before/after file SHA-256 values matched.", + "source_transition_note": "This hash identifies the implementation at this execution. Later restored controls include the UNKNOWN-prior integration guard, continued missing-end disclosure, and the additional lower/upper valid-fillings handling; those edits are not represented by this earlier execution hash." + }, + { + "name": "rethrow_unknown_earnings_completion_error", + "before": " if unknown:\n _refuse(\n InsuredUnsupportedReason.UNKNOWN_EARNINGS,\n \"Unknown earnings decide a valid established current period\",\n )\n", + "after": " if False and unknown:\n _refuse(\n InsuredUnsupportedReason.UNKNOWN_EARNINGS,\n \"Unknown earnings decide a valid established current period\",\n )\n", + "failed_tests": [ + "tests/test_track_b_insured_status_fix_round_4_routes.py::test_unknown_earnings_can_place_insured_start_before_declared_end", + "tests/test_track_b_insured_status_fix_round_4_routes.py::test_unknown_earnings_before_declared_end_retains_denominator_row", + "tests/test_track_b_insured_status_fix_round_4_routes.py::test_unknown_earnings_can_avoid_derived_prior_quarter_overlap" + ], + "command": "POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/round4-epuf POPULACE_DYNAMICS_PSID_DIR=/nonexistent/round4-psid PYTHONPATH=$PWD/src:$PWD OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\np=Path('src/populace_dynamics/track_b/insured_status.py')\ns=p.read_text()\nbefore=hashlib.sha256(p.read_bytes()).hexdigest()\nold=\" if unknown:\\n _refuse(\\n InsuredUnsupportedReason.UNKNOWN_EARNINGS,\\n \\\"Unknown earnings decide a valid established current period\\\",\\n )\\n\"\nreplacement=\" if False and unknown:\\n _refuse(\\n InsuredUnsupportedReason.UNKNOWN_EARNINGS,\\n \\\"Unknown earnings decide a valid established current period\\\",\\n )\\n\"\nassert s.count(old)==1\nexec(compile(s.replace(old,replacement), '', 'exec'), i.__dict__)\nresult=pytest.main([\"-q\",\"-p\",\"no:xdist\",\"-p\",\"no:cacheprovider\",\"tests/test_track_b_insured_status_fix_round_4_routes.py::test_unknown_earnings_can_place_insured_start_before_declared_end\",\"tests/test_track_b_insured_status_fix_round_4_routes.py::test_unknown_earnings_before_declared_end_retains_denominator_row\",\"tests/test_track_b_insured_status_fix_round_4_routes.py::test_unknown_earnings_can_avoid_derived_prior_quarter_overlap\",\"--tb=short\"])\nafter=hashlib.sha256(p.read_bytes()).hexdigest()\nprint('MUTATION rethrow-lower-completion pytest_exit',result,'source_sha256',before,'unchanged',before==after)\nassert before==after\nraise SystemExit(result)\nPY", + "summary": "3 failed in 59.90s; rethrowing a completion input error discards valid opposite-endpoint fillings for both a declared end and a derived prior-quarter boundary.", + "source_hash": "735245b19fce6f2439c222acac2956761032971c8fced8fde2f56d372b2abb95", + "source_hash_unchanged_after_run": true, + "isolated": true, + "restored": true, + "restoration": "The substituted source ran only in an isolated Python module namespace; the working-tree file SHA-256 matched before and after. Process exit discarded the mutation.", + "transitional_attempt": "An earlier rethrow run caught two declared-end tests, but its post-run source-hash assertion failed because the root concurrently changed the central guard (start hash48d27dbadf2cd3d2f3598488d628144589a0c74a84ce1dca2a4eeed0ac7f106d). That transitional attempt is not the final validated mutation record; the repeated stable-source run above caught all three deterministic cases." + }, + { + "name": "discard_unknown_earnings_upper_representation_alternative", + "before": " # candidate; a public completion failure then receives a refusal.\n return (\n", + "after": " # candidate; a public completion failure then receives a refusal.\n return False and (\n", + "failed_tests": [ + "tests/test_track_b_insured_status_fix_round_4_routes.py::test_unknown_earnings_can_avoid_derived_prior_quarter_overlap" + ], + "command": "POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/round4-epuf POPULACE_DYNAMICS_PSID_DIR=/nonexistent/round4-psid PYTHONPATH=$PWD/src:$PWD OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\np=Path('src/populace_dynamics/track_b/insured_status.py')\ns=p.read_text()\nbefore=hashlib.sha256(p.read_bytes()).hexdigest()\nold=\" # candidate; a public completion failure then receives a refusal.\\n return (\\n\"\nreplacement=\" # candidate; a public completion failure then receives a refusal.\\n return False and (\\n\"\nassert s.count(old)==1\nexec(compile(s.replace(old,replacement), '', 'exec'), i.__dict__)\nresult=pytest.main([\"-q\",\"-p\",\"no:xdist\",\"-p\",\"no:cacheprovider\",\"tests/test_track_b_insured_status_fix_round_4_routes.py::test_unknown_earnings_can_avoid_derived_prior_quarter_overlap\",\"--tb=short\"])\nafter=hashlib.sha256(p.read_bytes()).hexdigest()\nprint('MUTATION discard-unknown-upper-alternative pytest_exit',result,'source_sha256',before,'unchanged',before==after)\nassert before==after\nraise SystemExit(result)\nPY", + "summary": "1 failed in 31.09s; discarding the UNKNOWN-credit representative alternative incorrectly rejects a valid lower-credit start after a legal historical prior freeze.", + "source_hash": "735245b19fce6f2439c222acac2956761032971c8fced8fde2f56d372b2abb95", + "source_hash_unchanged_after_run": true, + "isolated": true, + "restored": true, + "restoration": "The substituted source ran only in an isolated Python module namespace; the working-tree file SHA-256 matched before and after. Process exit discarded the mutation." + }, + { + "name": "unknown_end_two_point_candidates", + "before": "range(_qid(start), last + 1)", + "after": "(last,)", + "summary": "1 failed in 25.88s; restoring the query-quarter and continuation candidates misses an earlier insured completion and fails DID NOT RAISE InsuredConfigurationUnsupported.", + "sourcehash_note": "The root agent changed only module/public docstring qualifications during this isolated run. The mutation process never wrote the source file; the root confirmed the behavioral implementation was unchanged.", + "isolated": true, + "restored": true, + "failed_tests": [ + "tests/test_track_b_insured_status_fix_round_4_endings.py::test_unknown_end_retains_disagreeing_earlier_end_and_denominator_row[earlier-administrative-end]" + ], + "source_hash": "d9eb7ded5e44dcaa1496eb39c336d9dec9ae8d6844924a43dea2cb29cb1494a0", + "source_hash_after": "042488e8b685ee4a5d4a608073762439e781242d416c587152628eb8b656df16", + "reproduction_command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round4-epuf POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round4-psid PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\nsource = Path(i.__file__).read_text()\nbefore = 'range(_qid(start), last + 1)'\nafter = '(last,)'\nassert source.count(before) == 1\nexec(compile(source.replace(before, after), i.__file__, 'exec'), i.__dict__)\nraise SystemExit(pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', 'tests/test_track_b_insured_status_fix_round_4_endings.py::test_unknown_end_retains_disagreeing_earlier_end_and_denominator_row', '--tb=short']))\nPY", + "runner_note": "Single-substitution canonical-module execution in an isolated process before named test collection. Reproduction command expresses the executed protocol; execution hashes identify its snapshot. FRA parameter IDs later gained UNKNOWN-prior variants. Replay selectors intentionally use the whole current parametrized function; historical failing IDs/counts above are unchanged." + }, + { + "name": "unknown_end_disappears_at_fra", + "before": " and person.current_disability_period_end is None\n", + "after": " and person.current_disability_period_end is None and month < _fra_date(person).replace(day=1)\n", + "summary": "2 failed in 24.45s; the FRA cap incorrectly erases current_disability_period_end from unknown_facts.", + "isolated": true, + "restored": true, + "failed_tests": [ + "tests/test_track_b_insured_status_fix_round_4_endings.py::test_unknown_end_remains_unknown_at_and_after_fra_when_status_agrees[month0]", + "tests/test_track_b_insured_status_fix_round_4_endings.py::test_unknown_end_remains_unknown_at_and_after_fra_when_status_agrees[month1]" + ], + "source_hash": "042488e8b685ee4a5d4a608073762439e781242d416c587152628eb8b656df16", + "source_hash_after": "042488e8b685ee4a5d4a608073762439e781242d416c587152628eb8b656df16", + "reproduction_command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round4-epuf POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round4-psid PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\nsource = Path(i.__file__).read_text()\nbefore = ' and person.current_disability_period_end is None\\n'\nafter = ' and person.current_disability_period_end is None and month < _fra_date(person).replace(day=1)\\n'\nassert source.count(before) == 1\nexec(compile(source.replace(before, after), i.__file__, 'exec'), i.__dict__)\nraise SystemExit(pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', 'tests/test_track_b_insured_status_fix_round_4_endings.py::test_unknown_end_remains_unknown_at_and_after_fra_when_status_agrees', '--tb=short']))\nPY", + "runner_note": "Single-substitution canonical-module execution in an isolated process before named test collection. Reproduction command expresses the executed protocol; execution hashes identify its snapshot. FRA parameter IDs later gained UNKNOWN-prior variants. Replay selectors intentionally use the whole current parametrized function; historical failing IDs/counts above are unchanged." + }, + { + "name": "annual_counts_ignore_earlier_endings", + "before": " for p in people\n", + "after": " for p in people[-1:]\n", + "summary": "1 failed in 5.37s; the annual upper bound zero misses the concrete earlier-ending count one.", + "isolated": true, + "restored": true, + "failed_tests": [ + "tests/test_track_b_insured_status_fix_round_4_endings.py::test_unknown_end_annual_count_envelope_contains_earlier_completions" + ], + "source_hash": "042488e8b685ee4a5d4a608073762439e781242d416c587152628eb8b656df16", + "source_hash_after": "042488e8b685ee4a5d4a608073762439e781242d416c587152628eb8b656df16", + "reproduction_command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round4-epuf POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round4-psid PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\nsource = Path(i.__file__).read_text()\nbefore = ' for p in people\\n'\nafter = ' for p in people[-1:]\\n'\nassert source.count(before) == 1\nexec(compile(source.replace(before, after), i.__file__, 'exec'), i.__dict__)\nraise SystemExit(pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', 'tests/test_track_b_insured_status_fix_round_4_endings.py::test_unknown_end_annual_count_envelope_contains_earlier_completions', '--tb=short']))\nPY", + "runner_note": "Single-substitution canonical-module execution in an isolated process before named test collection. Reproduction command expresses the executed protocol; execution hashes identify its snapshot. FRA parameter IDs later gained UNKNOWN-prior variants. Replay selectors intentionally use the whole current parametrized function; historical failing IDs/counts above are unchanged." + }, + { + "name": "dli_ignores_earlier_endings", + "before": " for p in lo_completions\n", + "after": " for p in lo_completions[-1:]\n", + "summary": "1 failed in 11.31s; explicit nonblind query_quarters=8, late=0 has mutant lower DLI 2024-03-31, which excludes the earlier-ending concrete DLI 2023-03-31.", + "isolated": true, + "restored": true, + "failed_tests": [ + "tests/test_track_b_insured_status_fix_round_4_endings.py::test_unknown_end_dli_contains_every_administrative_end_completion" + ], + "source_hash": "042488e8b685ee4a5d4a608073762439e781242d416c587152628eb8b656df16", + "source_hash_after": "042488e8b685ee4a5d4a608073762439e781242d416c587152628eb8b656df16", + "reproduction_command": "OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round4-epuf POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round4-psid PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\nsource = Path(i.__file__).read_text()\nbefore = ' for p in lo_completions\\n'\nafter = ' for p in lo_completions[-1:]\\n'\nassert source.count(before) == 1\nexec(compile(source.replace(before, after), i.__file__, 'exec'), i.__dict__)\nraise SystemExit(pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', 'tests/test_track_b_insured_status_fix_round_4_endings.py::test_unknown_end_dli_contains_every_administrative_end_completion', '--tb=short']))\nPY", + "runner_note": "Single-substitution canonical-module execution in an isolated process before named test collection. Reproduction command expresses the executed protocol; execution hashes identify its snapshot. FRA parameter IDs later gained UNKNOWN-prior variants. Replay selectors intentionally use the whole current parametrized function; historical failing IDs/counts above are unchanged." + } + ], + "round_4_note": "Nine implementation mutations were caught in isolated in-memory module namespaces; no mutation was written to the working tree. Final source includes the UNKNOWN-prior concrete-enumeration guard, explicit missing-end disclosure, and sound refusal for invalid lower/upper earnings representatives when a valid completion remains possible. Existing concrete assertions remain; final controls and exact commands are in the fix-round-4 report.", + "round_4_final_source_sha256": "735245b19fce6f2439c222acac2956761032971c8fced8fde2f56d372b2abb95" } diff --git a/docs/design/track_b_insured_status_rulespec_issue.md b/docs/design/track_b_insured_status_rulespec_issue.md index a5272af23..47a6c6712 100644 --- a/docs/design/track_b_insured_status_rulespec_issue.md +++ b/docs/design/track_b_insured_status_rulespec_issue.md @@ -110,8 +110,15 @@ case inventory, preserving its coverage labels. In particular: defect rather than silently inventing its intended fiscal boundary. - Compare fully-insured requirements against every captured CFR 404.115 birth-cohort row, including historical male transitions and January 1 - birthdays. The RS 00301.800 HTML lacks the linked exhibit's bytes, so - request the exhibit capture before claiming a .800 differential. + birthdays. Run the .800 table differential against the retained + `poms_rs_00301_800_exhibit_pdftotext.txt` capture (SHA-256 + `4459a0bccfc9d025973f3c9183042375780d6ee3f1a9f7e91b603490ba5a3a79`). + Its manifest retains the original PDF response hash + `9dcf53be30f06978b50e109ace88265ac38753700bb0093cb6213e01920af22f` + and the two GIF response hashes + `5e25a2e1dd124aa218af34b93f284049e9516612955ae1326ceff19160bd28bc` + and `65d94bae34becf54cf40e361cb6fb5668883f164efdff371122e8d2b9717efe3`. + No new exhibit capture is needed. - Exercise subsequent disability .140/.147 examples with all-or-none freeze handling and creditable endpoint quarters. Preserve any source-versus-rule discrepancy documented by the Python lane; do not make the compiler diff --git a/src/populace_dynamics/track_b/insured_status.py b/src/populace_dynamics/track_b/insured_status.py index 361d7659d..079d614dc 100644 --- a/src/populace_dynamics/track_b/insured_status.py +++ b/src/populace_dynamics/track_b/insured_status.py @@ -8,10 +8,13 @@ Medical onset declares continuous disability through the query month; it never establishes an administrative period of disability. An established period ends no later than the month before full retirement age; an unknown -ending is bounded rather than fabricated at the query. Disability tests +ending includes every candidate end quarter from insured start through +query/cap and permitted continuation. The cap never establishes the end. +Disability tests scan onset and later quarters; period establishment and section 214(c) -applicability carry explicit provenance. Impossible UNKNOWN histories are -rejected before any coverage refusal. Observable specialist credit +applicability carry explicit provenance. A declaration is rejected only +when every ordinary and possible specialist completion is impossible; +short DIB-entitled prior periods remain possible. Observable specialist credit alternatives cannot silently produce ordinary-only uninsured answers. The query month is a hypothetical entitlement month, not medical or administrative adjudication. Annual QC assignment is favorable and @@ -678,8 +681,10 @@ def _observable_coverage_paths( Act 213(c), 404.110(d), and RS 00301.315 make the pre1951 aggregate method available independently of an optional specialist flag. Its application, retroactivity and section227 conditions are not declared. - Act213(c) has no seven-EY limitation, unlike 404.110(d) and RS .315; - a potentially decisive path is refused without deciding that conflict. + RS .315 B.1.a describes the 1967 seven-EY condition; B.1.b removes + it under the 1990 amendments. 404.110(d)(1)(ii) supplies a June1992 + application exception with section227 conditions. A potentially + decisive path is refused without fabricating these filing facts. Direct QC declarations supply credited quarters, not raw wage totals. RS 00301.480 likewise reveals a possible pre1956 alternate disability path from onset and earnings; its application facts remain unmodeled. @@ -726,6 +731,7 @@ def _observable_coverage_paths( is EarningsProvenance.UNKNOWN ): required = 6 + # Source conflict us:oasdi-insured-pre1951-seven-elapsed-years if unknown_wages or ( wages >= 400 and wages // 400 + post1950 >= required ): @@ -734,31 +740,39 @@ def _observable_coverage_paths( "Pre1951 wages may establish fully insured status under " "Act213(c); filing and retroactivity facts are unmodeled", ) - elif ( - kind is InsuredTest.DISABILITY - and person.disability_onset is not None - and person.disability_onset < date(1956, 1, 1) + elif kind is InsuredTest.DISABILITY and _pre1956_alternate_possible( + person, upper, month, exit_month ): - first = max(_qid(person.disability_onset), 1952 * 4 + 2) - last = min(_qid(month), 1955 * 4 + 3) - for quarter in range(first, last + 1): - rows, _ = _world(person, upper, quarter, exit_month, False) - continuous = tuple(range(1951 * 4, quarter)) - assigned = { - qc - for row in rows.values() - for qc in _assign_qcs(*row, window=continuous) - } - if ( - len(assigned) >= 20 - and len(continuous) >= 6 - and set(continuous) <= assigned - ): - _refuse( - InsuredUnsupportedReason.DISABILITY_BEFORE_1956, - "Onset and QCs allow the RS00301.480 alternate test; " - "application conditions are unmodeled", - ) + _refuse( + InsuredUnsupportedReason.DISABILITY_BEFORE_1956, + "Onset and QCs allow the RS00301.480 alternate test; " + "application conditions are unmodeled", + ) + + +def _pre1956_alternate_possible(person, credits, month, exit_month): + """RS00301.480 possibility, without guessing filing eligibility.""" + if person.disability_onset is None or person.disability_onset >= date( + 1956, 1, 1 + ): + return False + first = max(_qid(person.disability_onset), 1952 * 4 + 2) + last = min(_qid(month), 1955 * 4 + 3) + for quarter in range(first, last + 1): + rows, _ = _world(person, credits, quarter, exit_month, False) + continuous = tuple(range(1951 * 4, quarter)) + assigned = { + qc + for row in rows.values() + for qc in _assign_qcs(*row, window=continuous) + } + if ( + len(assigned) >= 20 + and len(continuous) >= 6 + and set(continuous) <= assigned + ): + return True + return False def _credits(year, row, upper): @@ -1001,8 +1015,10 @@ def _unknown_prior_history_is_empty(person, credits, month, exit_month): """Prove infeasibility of the earliest nonempty prior period only. The earliest period must begin insured without any earlier exclusions - (404.320(b)(2), 404.321(a)), fit before onset and FRA, and leave five - months before its ending month (404.320(b)(4)). Upper-credit witnesses + (404.320(b)(2), 404.321(a)), and fit before onset and FRA. Act216(i) + (2)(A) also permits a single DIB-entitled month; 404.315(a)(4) waives + waiting in specified cases. No five-month premise is safe here. + Upper-credit witnesses deliberately overapproximate possibility. A surviving quarter proves no actual history; it only prevents an invalid-input conclusion. """ @@ -1028,15 +1044,24 @@ def _unknown_prior_history_is_empty(person, credits, month, exit_month): prior_disability_periods_provenance=EarningsProvenance.OBSERVED, prior_disability_periods_convention_id=None, ) - last_month = latest_end.year * 12 + latest_end.month - 1 for quarter in range(first, _qid(latest_end) + 1): start = max(person.birth_date, _qdate(quarter)) if start >= _fra_date(person): break - # Permissive about partial first/last months: only use this bound - # to prove impossibility, never to establish a period or its dates. - if start.year * 12 + start.month - 1 + 5 > last_month: - break + # A one-month DIB-entitled period may start and end this month. + # Overapproximate partial months too; this never establishes one. + possible_prior = replace( + plain, + disability_onset=start, + current_disability_period_established=False, + current_disability_period_end=None, + current_disability_period_end_provenance=EarningsProvenance.UNKNOWN, + current_disability_period_end_convention_id=None, + ) + if _pre1956_alternate_possible( + possible_prior, credits, start, exit_month + ): + return False if _witness( plain, credits, @@ -1148,17 +1173,10 @@ def _period_end_unknown(person, month): return ( person.current_disability_period_established and person.current_disability_period_end is None - and month < _fra_date(person).replace(day=1) - and ( - person.death_date is None - or person.death_date.replace(day=1) > month - ) ) -def _with_current_period( - person, credits, month, exit_month, *, earliest_end=False -): +def _with_current_period(person, credits, month, exit_month): if not person.current_disability_period_established: return person, None fra = _fra_date(person) @@ -1179,22 +1197,13 @@ def _with_current_period( else quarter ) # 416(i)(2)(B)/(D), 404.321: the query is an observation cut-off, - # never an ending fact. Without an end declaration, compare completion - # in this quarter with continuation to the statutory FRA boundary. + # never an ending fact. This is the latest possible completion; the + # caller separately enumerates earlier unknown administrative endings. end = fra.replace(day=1) - timedelta(days=1) if start >= fra or start > end: raise InvalidFamilyInput("Established period begins at or after FRA") if person.current_disability_period_end is not None: end = min(end, person.current_disability_period_end) - elif earliest_end: - end = min( - end, - date( - month.year, - month.month, - calendar.monthrange(month.year, month.month)[1], - ), - ) if person.death_date is not None: end = min(end, person.death_date) if end < start: @@ -1212,6 +1221,115 @@ def _with_current_period( ) +def _current_period_completions(person, completed, start, month): + """Every possible end quarter through query, plus continuation. + + 416(i)(2)(D) and 404.321(c) give alternative administrative endings. + FRA/death cap the range; neither establishes its actual ending. + End days within one quarter have identical insurance semantics. + """ + if ( + start is None + or person.prior_disability_periods_provenance + is EarningsProvenance.UNKNOWN + or not _period_end_unknown(person, month) + ): + return (completed,) + cap = completed.prior_disability_periods[-1].end + last = min(_qid(month), _qid(cap)) + endings = [ + min(_qend(quarter), cap) for quarter in range(_qid(start), last + 1) + ] + if _qid(cap) > _qid(month): + endings.append(cap) + return tuple( + replace( + completed, + prior_disability_periods=person.prior_disability_periods + + (DisabilityPeriod(start, end),), + ) + for end in endings + ) + + +def _specialist_establishment_possible( + person, years, credits, month, exit_month +): + """Overapproximate flagged/observable alternatives to ordinary insurance. + + Final direct QC declarations already supply the credited quarters; + unknown years already permit four. RR annual credits after 1977 use + the ordinary method (RS00301.230/.350). That flag alone cannot add QCs + to this complete direct-QC envelope. + Other specialist declarations are retained rather than adjudicated. + """ + for condition in person.conditions: + if condition is CoverageCondition.RAILROAD_CREDITS and all( + row.qc_count is not None + or row.qc_quarters is not None + or row.provenance is EarningsProvenance.UNKNOWN + for row in years.values() + ): + continue + return True + return _pre1956_alternate_possible(person, credits, month, exit_month) + + +def _could_establish_current_period( + person, years, credits, month, exit_month, maximum_qcs +): + """Reject only a declaration impossible under every possible route. + + This is deliberately one-way: yes preserves a candidate or a named + refusal; it never establishes a period. Calendar/schema contradictions + have already been rejected. Ordinary premises cannot exclude a + specialist route or a short DIB-entitled prior period. + """ + if not person.current_disability_period_established: + return True + if _specialist_establishment_possible( + person, years, credits, month, exit_month + ): + return True + if maximum_qcs < 6: + return False + if ( + person.prior_disability_periods_provenance + is EarningsProvenance.UNKNOWN + and not _unknown_prior_history_is_empty( + person, credits, month, exit_month + ) + ): + return True + plain = replace( + person, + prior_disability_periods_provenance=EarningsProvenance.OBSERVED, + prior_disability_periods_convention_id=None, + ) + try: + _with_current_period(plain, credits, month, exit_month) + except InvalidFamilyInput: + # More credits can move the first insured start across a declared + # end or a represented prior-period boundary. Failure to construct + # that upper-credit period is not proof about every completion. + # Retain any UNKNOWN-credit declaration with an ordinary insured + # candidate; a public completion failure then receives a refusal. + return ( + any( + row.provenance is EarningsProvenance.UNKNOWN + for row in years.values() + ) + and _decision_witness( + plain, + credits, + min(month, _fra_date(plain).replace(day=1)), + exit_month, + InsuredTest.DISABILITY, + )[0][0] + ) + return True + + def _dli_cap(person, month, exit_month): cap = min(_qid(month), _fra_quarter(person) - 1) if exit_month is not None and exit_month <= month: @@ -1241,7 +1359,8 @@ def insured_status( the ending changes a requested status, and is always capped before FRA. Each disability window ends at its tested quarter, from onset through query, and the first insured quarter supplies the witness (404.131). - Impossible establishment is an input error even with UNKNOWN history. + Establishment is an input error only if no ordinary, observable, or + flagged specialist route could validate any completion of the facts. No entry date, imputation, or pre-entry zero convention exists. """ _validate_history( @@ -1264,7 +1383,7 @@ def insured_status( and person.current_disability_period_provenance is EarningsProvenance.UNKNOWN ) - end_unknown = _period_end_unknown(person, month) and not prior_unknown + end_unknown = _period_end_unknown(person, month) max_rows, _ = _world( person, upper, @@ -1274,32 +1393,24 @@ def insured_status( include_zero=True, ) maximum_qcs = sum(len(_assign_qcs(*row)) for row in max_rows.values()) - if person.current_disability_period_established and maximum_qcs < 6: + if not _could_establish_current_period( + person, years, upper, month, coverage_end_month, maximum_qcs + ): raise InvalidFamilyInput( - "Established current period requires at least six lifetime QCs" + "Established current period has no possible insured disabled quarter" ) + _coverage_checks(person, years, month, totalization_credits) if ( person.current_disability_period_established - and prior_unknown - and _unknown_prior_history_is_empty( + and _pre1956_alternate_possible( person, upper, month, coverage_end_month ) ): - # Empty is the only possible prior history. Validate establishment - # in that concrete world before retaining any coverage refusal. - # Keep the caller's UNKNOWN provenance and conservative output - # envelope if it is valid; no observed fact is invented here. - plain = replace( - person, - prior_disability_periods_provenance=EarningsProvenance.OBSERVED, - prior_disability_periods_convention_id=None, + _refuse( + InsuredUnsupportedReason.DISABILITY_BEFORE_1956, + "RS00301.480 may establish the declared current period; " + "application conditions are unmodeled", ) - _with_current_period(plain, upper, month, coverage_end_month) - if person.current_disability_period_established and not prior_unknown: - # Even the most favorable earnings completion must supply a legal - # insured start before FRA. Input errors precede coverage refusals. - _with_current_period(person, upper, month, coverage_end_month) - _coverage_checks(person, years, month, totalization_credits) applicability = _sspa211_applicability(person) # Known applicable cases require unimplemented work-authorization/visa # adjudication. Unknown applicability can decide a QC-only false result. @@ -1328,46 +1439,40 @@ def insured_status( else: uncertain_current_start = True else: - if person.current_disability_period_established: - initial_lo, _ = _decision_witness( - person, - lower, - month, - coverage_end_month, - InsuredTest.DISABILITY, + try: + lo_person, lo_start = _with_current_period( + person, lower, month, coverage_end_month ) - if not initial_lo[0] and unknown: - initial_hi, _ = _decision_witness( + hi_person, hi_start = ( + _with_current_period( person, upper, month, coverage_end_month, - InsuredTest.DISABILITY, ) - if initial_hi[0]: - _refuse( - InsuredUnsupportedReason.UNKNOWN_EARNINGS, - "Unknown facts decide the established current insured start", - ) - lo_person, lo_start = _with_current_period( - person, lower, month, coverage_end_month - ) - hi_person, hi_start = ( - _with_current_period( - person, - upper, - month, - coverage_end_month, - earliest_end=end_unknown, + if unknown + else (lo_person, lo_start) ) - if unknown or end_unknown - else (lo_person, lo_start) - ) + except InvalidFamilyInput: + if unknown: + _refuse( + InsuredUnsupportedReason.UNKNOWN_EARNINGS, + "Unknown earnings decide a valid established current period", + ) + # With known credits the shared possibility predicate already + # validated this identical construction before any refusal. + raise if lo_start != hi_start: _refuse( InsuredUnsupportedReason.UNKNOWN_EARNINGS, "Unknown earnings decide established current period start", ) + lo_completions = _current_period_completions( + person, lo_person, lo_start, month + ) + hi_completions = _current_period_completions( + person, hi_person, hi_start, month + ) # The current disability is known only through the query. A frozen-exit # future DLI would require its unobserved recovery/end date. if ( @@ -1395,54 +1500,40 @@ def insured_status( # Establishment follows the first insured quarter; using its own # exclusion to prove that quarter would be circular. Subsequent # hypothetical-onset DLI quarters can use the established period. - decision_lo_person = ( - person if kind is InsuredTest.DISABILITY else lo_person - ) - decision_hi_person = ( - person if kind is InsuredTest.DISABILITY else hi_person + decision_lo_people = ( + (person,) if kind is InsuredTest.DISABILITY else lo_completions ) - lo, lo_quarter = _decision_witness( - decision_lo_person, lower, month, coverage_end_month, kind + decision_hi_people = ( + (person,) if kind is InsuredTest.DISABILITY else hi_completions ) - hi, hi_quarter = ( - _decision_witness( - decision_hi_person, upper, month, coverage_end_month, kind - ) - if unknown or end_unknown - else (lo, lo_quarter) + lo_candidates = [ + _decision_witness(p, lower, month, coverage_end_month, kind) + for p in decision_lo_people + ] + hi_candidates = ( + [ + _decision_witness(p, upper, month, coverage_end_month, kind) + for p in decision_hi_people + ] + if unknown + else lo_candidates ) + lo, lo_quarter = lo_candidates[-1] + hi, hi_quarter = hi_candidates[0] if end_unknown: - same_earnings_end, _ = _decision_witness( - ( - person - if kind is InsuredTest.DISABILITY - else _with_current_period( - person, - lower, - month, - coverage_end_month, - earliest_end=True, - )[0] - ), - lower, - month, - coverage_end_month, - kind, - ) - if lo[0] != same_earnings_end[0]: + if any(witness[0] != lo[0] for witness, _ in lo_candidates) or any( + witness[0] != hi[0] for witness, _ in hi_candidates + ): _refuse( InsuredUnsupportedReason.CURRENT_PERIOD_END, f"Unobserved statutory period end decides {kind.value}", ) - _observable_coverage_paths( - decision_lo_person, - years, - month, - coverage_end_month, - kind, - lo, - upper, - ) + for p, (witness, _) in zip( + decision_lo_people, lo_candidates, strict=True + ): + _observable_coverage_paths( + p, years, month, coverage_end_month, kind, witness, upper + ) if lo[0] != hi[0]: _refuse( InsuredUnsupportedReason.UNKNOWN_EARNINGS, @@ -1488,15 +1579,16 @@ def insured_status( and len(_events(person, month, kind)) > 1 ) ) + witnesses = [value for value, _ in lo_candidates + hi_candidates] count_lo, count_hi = ( (0, maximum_qcs) if broad - else (min(lo[1], hi[1]), max(lo[1], hi[1])) + else (min(w[1] for w in witnesses), max(w[1] for w in witnesses)) ) full_lo, full_hi = ( (0, maximum_qcs) if broad - else (min(lo[7], hi[7]), max(lo[7], hi[7])) + else (min(w[7] for w in witnesses), max(w[7] for w in witnesses)) ) decisions[kind] = _computed( StatusDecision, @@ -1520,14 +1612,22 @@ def insured_status( ) dli = None if test in (InsuredTest.ALL, InsuredTest.DISABILITY): - lo_date, lo_censored = _last_insured( - lo_person, lower, month, coverage_end_month - ) - hi_date, hi_censored = ( - _last_insured(hi_person, upper, month, coverage_end_month) - if unknown or end_unknown - else (lo_date, lo_censored) + lower_dates = [ + _last_insured(p, lower, month, coverage_end_month) + for p in lo_completions + ] + upper_dates = ( + [ + _last_insured(p, upper, month, coverage_end_month) + for p in hi_completions + ] + if unknown + else lower_dates ) + lo_date = min((d for d, _ in lower_dates), key=lambda d: d or date.min) + hi_date = max((d for d, _ in upper_dates), key=lambda d: d or date.min) + lo_censored = any(c for _, c in lower_dates) + hi_censored = any(c for _, c in upper_dates) if (prior_unknown or current_unknown) and maximum_qcs >= 6: hi_date = _dli_cap(person, month, coverage_end_month) hi_censored = ( @@ -1556,6 +1656,21 @@ def insured_status( include_zero=True, ) assigned = {y: _assign_qcs(*row) for y, row in lo_rows.items()} + completion_rows = [ + _world( + p, + credits, + _qid(month), + coverage_end_month, + True, + include_zero=True, + )[0] + for people, credits in ( + (lo_completions, lower), + (hi_completions, upper), + ) + for p in people + ] unknown_facts = tuple( name for name, missing in ( @@ -1600,12 +1715,18 @@ def insured_status( ( 0 if prior_unknown or current_unknown - else len(assigned[y]) + else min( + len(_assign_qcs(*rows[y])) + for rows in completion_rows + ) ), ( len(_assign_qcs(*max_rows[y])) if prior_unknown or current_unknown - else len(_assign_qcs(*hi_rows[y])) + else max( + len(_assign_qcs(*rows[y])) + for rows in completion_rows + ) ), ) for y in lo_rows diff --git a/tests/README-tiers.md b/tests/README-tiers.md index ab263f5c9..f63751862 100644 --- a/tests/README-tiers.md +++ b/tests/README-tiers.md @@ -39,9 +39,9 @@ pytest --collect-only -q -m oracle_policyengine | tail -1 | Tier | Tests at HEAD | |---|---:| -| `unit` | 20,440 | +| `unit` | 20,493 | | `artifact` | 4,271 | | `integration_psid` | 1,471 | | `reproduction_legacy` | 520 | | `oracle_policyengine` | 308 | -| **Total** | **27,010** | +| **Total** | **27,063** | diff --git a/tests/test_track_b_insured_status_fix_round_2.py b/tests/test_track_b_insured_status_fix_round_2.py index 9fd5f53f0..5f2341a44 100644 --- a/tests/test_track_b_insured_status_fix_round_2.py +++ b/tests/test_track_b_insured_status_fix_round_2.py @@ -638,11 +638,31 @@ def test_unknown_current_period_refuses_when_establishment_changes_full_status() month, test=i.InsuredTest.ALL, ) + # Establishment is known here, but the administrative end remains a + # separate missing fact and earlier completions can change full status. + with pytest.raises(i.InsuredConfigurationUnsupported) as error: + i.insured_status( + replace( + person, + current_disability_period_established=True, + current_disability_period_provenance=( + i.EarningsProvenance.OBSERVED + ), + ), + years, + month, + test=i.InsuredTest.FULLY, + ) + assert error.value.reason is i.InsuredUnsupportedReason.CURRENT_PERIOD_END frozen = i.insured_status( replace( person, current_disability_period_established=True, current_disability_period_provenance=i.EarningsProvenance.OBSERVED, + current_disability_period_end=date(2047, 1, 31), + current_disability_period_end_provenance=( + i.EarningsProvenance.OBSERVED + ), ), years, month, diff --git a/tests/test_track_b_insured_status_fix_round_3_periods.py b/tests/test_track_b_insured_status_fix_round_3_periods.py index fccea1596..11c8ad235 100644 --- a/tests/test_track_b_insured_status_fix_round_3_periods.py +++ b/tests/test_track_b_insured_status_fix_round_3_periods.py @@ -4,6 +4,7 @@ or forecast claim. """ +import calendar from dataclasses import replace from datetime import date @@ -48,8 +49,19 @@ def test_ongoing_period_end_cannot_invent_a_credited_query_endpoint(): assert error.value.reason.value == ( "ongoing_disability_period_end_decides_status" ) + with pytest.raises(i.InsuredConfigurationUnsupported) as error: + i.insured_status( + person, years, date(2026, 4, 1), test=i.InsuredTest.CURRENTLY + ) + assert error.value.reason is i.InsuredUnsupportedReason.CURRENT_PERIOD_END + # Preserve the original running-period assertions with that end known. + continuing = replace( + person, + current_disability_period_end=date(2067, 1, 31), + current_disability_period_end_provenance=OBSERVED, + ) later = i.insured_status( - person, years, date(2026, 4, 1), test=i.InsuredTest.CURRENTLY + continuing, years, date(2026, 4, 1), test=i.InsuredTest.CURRENTLY ) assert not later.currently.insured assert later.currently.qc_count_lower == 5 @@ -69,9 +81,22 @@ def test_current_period_ends_before_fra_even_when_medical_disability_continues() person = _fra_person() month = date(2028, 10, 1) years = history(person, month, {y: 4 for y in range(2016, 2026)}) - result = i.insured_status( + bounded = i.insured_status( person, years, month, test=i.InsuredTest.CURRENTLY ) + assert not bounded.currently.insured + assert bounded.currently.qc_count_lower == 2 + assert bounded.currently.qc_count_upper == 5 + assert "current_disability_period_end" in bounded.unknown_facts + # The cap still yields exactly five credits when its ending is declared. + capped = replace( + person, + current_disability_period_end=date(2026, 12, 31), + current_disability_period_end_provenance=OBSERVED, + ) + result = i.insured_status( + capped, years, month, test=i.InsuredTest.CURRENTLY + ) assert not result.currently.insured assert result.currently.qc_count_lower == 5 @@ -246,7 +271,13 @@ def test_ongoing_period_completion_status_and_count_bounds_are_sound( {2016: 4, 2017: 4, 2020: counts[0], 2021: counts[1], 2026: current}, ) concrete = [] - for ending in [date(2026, 3, 31), date(2026, 6, 30), date(2027, 12, 31)]: + endings = [ + date(year, end_month, calendar.monthrange(year, end_month)[1]) + for year in range(2022, 2027) + for end_month in (3, 6, 9, 12) + if (year, end_month) <= (2026, 3) + ] + [date(2026, 6, 30), date(2027, 12, 31)] + for ending in endings: value = i.insured_status( replace( person, diff --git a/tests/test_track_b_insured_status_fix_round_4_docs.py b/tests/test_track_b_insured_status_fix_round_4_docs.py new file mode 100644 index 000000000..4a06849e9 --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_4_docs.py @@ -0,0 +1,29 @@ +"""Statutory conformance: retained insured-status dispatch evidence. + +Invented/captured source declarations only; no population or forecast claim. +""" + +import json +from pathlib import Path + + +def test_rulespec_dispatch_names_retained_exhibit_and_original_body_hashes(): + root = Path(__file__).resolve().parents[1] + dispatch = ( + root / "docs/design/track_b_insured_status_rulespec_issue.md" + ).read_text() + sources = json.loads( + ( + root / "tests/data/track_b/insured_status_sources/manifest.json" + ).read_text() + )["sources"] + exhibit = next( + source + for source in sources + if source["id"] == "poms_rs_00301_800_exhibit" + ) + assert exhibit["file"] in dispatch + assert exhibit["sha256"] in dispatch + for body in exhibit["served_bodies"]: + assert body["sha256"] in dispatch + assert "request the exhibit capture" not in dispatch diff --git a/tests/test_track_b_insured_status_fix_round_4_endings.py b/tests/test_track_b_insured_status_fix_round_4_endings.py new file mode 100644 index 000000000..686737904 --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_4_endings.py @@ -0,0 +1,303 @@ +"""Statutory conformance: unknown administrative endings cover all quarters. + +Invented cases and captured statutory authority only; no population, +behavioral, or forecast claim. +""" + +import calendar +import xml.etree.ElementTree as ET +from dataclasses import replace +from datetime import date +from fractions import Fraction +from pathlib import Path + +import pytest +from hypothesis import example, given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as i +from populace_dynamics.track_b.gross_benefits import count_family_outcomes +from tests.test_track_b_insured_status import history + +OBSERVED = i.EarningsProvenance.OBSERVED + + +def _person(**facts): + return i.Person( + date(2000, 2, 2), + disability_onset=date(2022, 1, 15), + statutory_blindness=True, + prior_disability_periods_provenance=OBSERVED, + current_disability_period_established=True, + current_disability_period_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + **facts, + ) + + +def _declared(person, ending): + return replace( + person, + current_disability_period_end=ending, + current_disability_period_end_provenance=OBSERVED, + ) + + +def _qend(quarter): + year, within_year = divmod(quarter, 4) + month = within_year * 3 + 3 + return date(year, month, calendar.monthrange(year, month)[1]) + + +def _endings(start, month, cap=date(2067, 1, 31)): + """Enumerate the brief's quarter completions, independently of the rule.""" + first = start.year * 4 + (start.month - 1) // 3 + last = min( + month.year * 4 + (month.month - 1) // 3, + cap.year * 4 + (cap.month - 1) // 3, + ) + values = [min(_qend(quarter), cap) for quarter in range(first, last + 1)] + # One completion strictly past the query represents a running period. + if cap > _qend(month.year * 4 + (month.month - 1) // 3): + values.append(min(_qend(last + 1), cap)) + return tuple(values) + + +@pytest.mark.parametrize( + "month,kind,counts,early_insured,early_required", + [ + ( + date(2026, 3, 1), + i.InsuredTest.CURRENTLY, + {2017: 1, 2020: 4, 2021: 1, 2025: 1}, + True, + 6, + ), + ( + date(2067, 2, 1), + i.InsuredTest.FULLY, + {2017: 1, 2020: 4, 2021: 1}, + False, + 37, + ), + ], + ids=["earlier-administrative-end", "fra-is-only-an-upper-bound"], +) +def test_unknown_end_retains_disagreeing_earlier_end_and_denominator_row( + month, kind, counts, early_insured, early_required +): + person = _person() + years = history(person, month, counts) + early = i.insured_status( + _declared(person, date(2024, 12, 31)), years, month, test=kind + ) + decision = getattr(early, kind.value) + assert decision.insured is early_insured + assert decision.required == early_required + assert decision.qc_count_lower == decision.qc_count_upper == 6 + + running = i.insured_status( + _declared(person, date(2067, 1, 31)), years, month, test=kind + ) + assert getattr(running, kind.value).insured is not early_insured + if kind is i.InsuredTest.CURRENTLY: + assert running.currently.qc_count_lower == 5 + assert running.currently.qc_count_upper == 5 + else: + assert running.fully.required == 6 + assert ( + running.fully.qc_count_lower == running.fully.qc_count_upper == 6 + ) + + with pytest.raises(i.InsuredConfigurationUnsupported) as error: + i.insured_status(person, years, month, test=kind) + assert error.value.reason is i.InsuredUnsupportedReason.CURRENT_PERIOD_END + row = i.evaluate_insured_status( + "unknown-administrative-end", + Fraction(1), + lambda: i.insured_status(person, years, month, test=kind), + ) + assert row.unsupported.reason is error.value.reason + denominator = count_family_outcomes([row]) + assert denominator.rows == denominator.unsupported_rows == 1 + assert denominator.weight == denominator.unsupported_weight == 1 + + +def _assert_count_envelope(unknown, concrete, kind): + bound = getattr(unknown, kind.value) + exact = getattr(concrete, kind.value) + assert bound.insured is exact.insured + assert bound.qc_count_lower <= exact.qc_count_lower + assert exact.qc_count_upper <= bound.qc_count_upper + assert bound.fully_qc_count_lower <= exact.fully_qc_count_lower + assert exact.fully_qc_count_upper <= bound.fully_qc_count_upper + for year, (lower, upper) in concrete.qcs_by_year.items(): + assert unknown.qcs_by_year[year][0] <= lower + assert upper <= unknown.qcs_by_year[year][1] + + +def test_unknown_end_count_envelope_contains_earliest_currently_completion(): + person = _person() + month = date(2026, 3, 1) + years = history(person, month, {2017: 1, 2020: 4, 2021: 1}) + unknown = i.insured_status( + person, years, month, test=i.InsuredTest.CURRENTLY + ) + assert not unknown.currently.insured + assert "current_disability_period_end" in unknown.unknown_facts + for ending in _endings(person.disability_onset, month): + concrete = i.insured_status( + _declared(person, ending), + years, + month, + test=i.InsuredTest.CURRENTLY, + ) + _assert_count_envelope(unknown, concrete, i.InsuredTest.CURRENTLY) + + +def test_unknown_end_annual_count_envelope_contains_earlier_completions(): + person = _person() + month = date(2026, 3, 1) + years = history(person, month, {2017: 1, 2020: 4, 2021: 1, 2025: 1}) + unknown = i.insured_status(person, years, month, test=i.InsuredTest.FULLY) + assert unknown.fully.insured + for ending in _endings(person.disability_onset, month): + concrete = i.insured_status( + _declared(person, ending), years, month, test=i.InsuredTest.FULLY + ) + _assert_count_envelope(unknown, concrete, i.InsuredTest.FULLY) + + +@pytest.mark.parametrize("month", [date(2067, 2, 1), date(2068, 2, 1)]) +@pytest.mark.parametrize("unknown_prior", [False, True]) +def test_unknown_end_remains_unknown_at_and_after_fra_when_status_agrees( + month, + unknown_prior, +): + person = _person() + if unknown_prior: + person = replace( + person, + prior_disability_periods_provenance=i.EarningsProvenance.UNKNOWN, + ) + years = history(person, month, {year: 4 for year in range(2012, 2022)}) + result = i.insured_status(person, years, month, test=i.InsuredTest.FULLY) + assert result.fully.insured + assert "current_disability_period_end" in result.unknown_facts + assert result.decided_despite_unknowns + for ending in (date(2022, 3, 31), date(2024, 12, 31), date(2067, 1, 31)): + concrete = i.insured_status( + _declared(person, ending), years, month, test=i.InsuredTest.FULLY + ) + _assert_count_envelope(result, concrete, i.InsuredTest.FULLY) + + +@settings(max_examples=12, deadline=None) +@example( + query_quarters=16, late=1, kind=i.InsuredTest.CURRENTLY, birth_shift=0 +) +@given( + query_quarters=st.integers(1, 16), + late=st.integers(0, 4), + kind=st.sampled_from([i.InsuredTest.FULLY, i.InsuredTest.CURRENTLY]), + birth_shift=st.integers(0, 3), +) +def test_unknown_end_status_and_every_count_cover_all_quarter_completions( + query_quarters, late, kind, birth_shift +): + person = replace( + _person(), + birth_date=date(2000 + birth_shift, 2, 2), + disability_onset=date(2022 + birth_shift, 1, 15), + ) + query = (2022 + birth_shift) * 4 + query_quarters + year, quarter = divmod(query, 4) + month = date(year, quarter * 3 + 1, 1) + years = history( + person, + month, + { + 2017 + birth_shift: 1, + 2020 + birth_shift: 4, + 2021 + birth_shift: 1, + month.year: late, + }, + ) + concrete = [ + i.insured_status(_declared(person, ending), years, month, test=kind) + for ending in _endings(person.disability_onset, month) + ] + try: + result = i.insured_status(person, years, month, test=kind) + except i.InsuredConfigurationUnsupported as error: + assert error.reason is i.InsuredUnsupportedReason.CURRENT_PERIOD_END + assert ( + len({getattr(value, kind.value).insured for value in concrete}) > 1 + ) + return + assert "current_disability_period_end" in result.unknown_facts + for value in concrete: + _assert_count_envelope(result, value, kind) + + +def _assert_dli_envelope(unknown, concrete): + if concrete.lower is not None: + assert unknown.lower is None or unknown.lower <= concrete.lower + else: + assert unknown.lower is None + if concrete.upper is not None: + assert unknown.upper is not None + assert concrete.upper <= unknown.upper + if concrete.right_censored: + assert unknown.right_censored + + +@settings(max_examples=8, deadline=None) +@example(query_quarters=8, late=0, blind=False) +@given( + query_quarters=st.integers(1, 8), + late=st.integers(0, 4), + blind=st.booleans(), +) +def test_unknown_end_dli_contains_every_administrative_end_completion( + query_quarters, late, blind +): + person = replace(_person(), statutory_blindness=blind) + query = 2022 * 4 + query_quarters + year, quarter = divmod(query, 4) + month = date(year, quarter * 3 + 1, 1) + years = history( + person, + month, + {2020: 4, 2021: 2, month.year: late}, + ) + result = i.insured_status( + person, years, month, test=i.InsuredTest.DISABILITY + ) + assert result.disability.insured + assert "current_disability_period_end" in result.unknown_facts + for ending in _endings(person.disability_onset, month): + concrete = i.insured_status( + _declared(person, ending), + years, + month, + test=i.InsuredTest.DISABILITY, + ) + _assert_count_envelope(result, concrete, i.InsuredTest.DISABILITY) + _assert_dli_envelope(result.dli, concrete.dli) + + +def test_earlier_administrative_ending_is_quoted_from_captured_authority(): + sources = Path(__file__).parent / "data/track_b/insured_status_sources" + cfr = "".join( + ET.fromstring( + (sources / "ecfr_20cfr404_321.xml").read_text() + ).itertext() + ) + assert "whichever of the following is the earliest" in cfr + assert "If you perform substantial gainful activity" in cfr + assert "the last month for which you received benefits" in cfr + act = (sources / "lii_usc_42_416_excerpts.txt").read_text() + assert "whichever of the following months is the earlier" in act + assert "the first month for which no benefit is payable" in act diff --git a/tests/test_track_b_insured_status_fix_round_4_routes.py b/tests/test_track_b_insured_status_fix_round_4_routes.py new file mode 100644 index 000000000..42fd98db1 --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_4_routes.py @@ -0,0 +1,540 @@ +"""Statutory conformance: every possible establishment route survives. + +Invented declarations and captured statutory rules only; no population, +behavioral, payment, or forecast claim. +""" + +from dataclasses import replace +from datetime import date +from fractions import Fraction + +import pytest +from hypothesis import example, given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as i +from populace_dynamics.track_b.gross_benefits import count_family_outcomes +from tests.test_track_b_insured_status import history +from tests.test_track_b_insured_status_sources import source_text + +OBSERVED = i.EarningsProvenance.OBSERVED +UNKNOWN = i.EarningsProvenance.UNKNOWN + + +def _short_period_case(): + person = i.Person( + date(2000, 2, 2), + disability_onset=date(2029, 1, 15), + statutory_blindness=True, + dib_entitlement_month=date(2028, 10, 1), + prior_disability_periods_provenance=UNKNOWN, + current_disability_period_established=True, + current_disability_period_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + month = date(2029, 4, 1) + return person, history(person, month, {2027: 2, 2028: 4}), month + + +def _pre1956_case(*, established=True, unknown_prior=False, earlier=14): + person = i.Person( + date(1900, 2, 2), + sex=i.Sex.FEMALE, + disability_onset=date(1952, 7, 15), + prior_disability_periods_provenance=( + UNKNOWN if unknown_prior else OBSERVED + ), + current_disability_period_established=established, + current_disability_period_provenance=( + UNKNOWN if established is None else OBSERVED + ), + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + month = date(1968, 2, 1) + counts = { + year: min(4, max(0, earlier - 4 * n)) + for n, year in enumerate(range(1938, 1942)) + } + counts.update({1951: 4, 1952: 2}) + return person, history(person, month, counts), month + + +def _declared_end_unknown_earnings_case(*, first=2, ending=date(2022, 3, 31)): + person = i.Person( + date(2000, 2, 2), + statutory_blindness=True, + disability_onset=date(2022, 1, 15), + prior_disability_periods_provenance=OBSERVED, + current_disability_period_established=True, + current_disability_period_provenance=OBSERVED, + current_disability_period_end=ending, + current_disability_period_end_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + month = date(2023, 1, 1) + years = history(person, month, {2020: first, 2021: 5 - first, 2023: 1}) + years[2022] = i.CoverageYear(UNKNOWN) + return person, years, month + + +def _prior_overlap_unknown_earnings_case(*, missing_year=1971): + person = i.Person( + date(1910, 2, 2), + sex=i.Sex.FEMALE, + disability_onset=date(1972, 2, 15), + prior_disability_periods=( + i.DisabilityPeriod(date(1952, 7, 15), date(1972, 1, 31)), + ), + prior_disability_periods_provenance=OBSERVED, + current_disability_period_established=True, + current_disability_period_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + month = date(1973, 1, 1) + counts = { + 1938: 4, + 1939: 4, + 1940: 4, + 1941: 2, + 1951: 4, + 1952: 2, + **{year: 4 for year in range(1967, 1972)}, + 1973: 1, + } + counts[missing_year] = 3 + years = history(person, month, counts) + years[1972] = i.CoverageYear(UNKNOWN) + # RS .480 permits this prior start with 20 total QCs and all six + # 1951Q1--1952Q2 QCs; its application alternative admits 1964 filing. + # The prior period exceeds five months and ends before FRA (.321). + assert ( + sum(counts[year] for year in (1938, 1939, 1940, 1941, 1951, 1952)) + == 20 + ) + assert years[1951].qc_quarters == (True,) * 4 + assert years[1952].qc_quarters[:2] == (True,) * 2 + return person, years, month + + +def _retained_row(person, years, month, test, *, reason=None): + row = i.evaluate_insured_status( + "invented-route", + Fraction(1), + lambda: i.insured_status(person, years, month, test=test), + ) + denominator = count_family_outcomes((row,)) + assert denominator.rows == 1 + assert denominator.weight == 1 + if reason is not None: + assert row.unsupported.reason is reason + if row.unsupported is not None: + assert denominator.unsupported_rows == 1 + assert denominator.unsupported_weight == 1 + else: + assert denominator.unsupported_rows == 0 + assert denominator.unsupported_weight == 0 + return row + + +def test_unknown_earnings_can_place_insured_start_before_declared_end(): + person, years, month = _declared_end_unknown_earnings_case() + with pytest.raises(i.InsuredConfigurationUnsupported) as error: + i.insured_status(person, years, month, test=i.InsuredTest.FULLY) + assert error.value.reason is i.InsuredUnsupportedReason.UNKNOWN_EARNINGS + + +def test_unknown_earnings_before_declared_end_retains_denominator_row(): + person, years, month = _declared_end_unknown_earnings_case() + _retained_row( + person, + years, + month, + i.InsuredTest.FULLY, + reason=i.InsuredUnsupportedReason.UNKNOWN_EARNINGS, + ) + + +@settings(max_examples=8, deadline=None) +@example(first=2, ending_month=3) +@given( + first=st.integers(1, 4), + ending_month=st.sampled_from([1, 3, 12]), +) +def test_possible_unknown_earnings_filling_prevents_declared_end_input_error( + first, ending_month +): + """An invalid lower completion never disproves a valid upper one.""" + person, years, month = _declared_end_unknown_earnings_case( + first=first, ending=date(2022, ending_month, 31) + ) + concrete_validity = [] + for count in range(5): + concrete = dict(years) + concrete[2022] = i.CoverageYear(OBSERVED, qc_count=count) + try: + result = i.insured_status( + person, concrete, month, test=i.InsuredTest.FULLY + ) + except i.InvalidFamilyInput: + concrete_validity.append(False) + else: + concrete_validity.append(True) + assert result.current_disability_period_start == date(2022, 1, 15) + assert concrete_validity == [False, True, True, True, True] + _retained_row( + person, + years, + month, + i.InsuredTest.FULLY, + reason=i.InsuredUnsupportedReason.UNKNOWN_EARNINGS, + ) + + +def test_unknown_earnings_can_avoid_derived_prior_quarter_overlap(): + person, years, month = _prior_overlap_unknown_earnings_case() + with pytest.raises(i.InsuredConfigurationUnsupported) as error: + i.insured_status(person, years, month, test=i.InsuredTest.FULLY) + assert error.value.reason is i.InsuredUnsupportedReason.UNKNOWN_EARNINGS + _retained_row( + person, + years, + month, + i.InsuredTest.FULLY, + reason=i.InsuredUnsupportedReason.UNKNOWN_EARNINGS, + ) + + +@settings(max_examples=4, deadline=None) +@example(missing_year=1971) +@given(missing_year=st.integers(1968, 1971)) +def test_possible_lower_earnings_filling_prevents_upper_overlap_input_error( + missing_year, +): + """An invalid upper-credit period cannot disprove every completion. + + The declared prior start meets the captured pre1956 alternate test. + Zero 1972 QCs yields an insured new start in 1973Q1. More 1972 QCs + move that start into the prior ending quarter, which the interface's + nonoverlapping-quarter representation rejects for that completion. + """ + person, years, month = _prior_overlap_unknown_earnings_case( + missing_year=missing_year + ) + concrete_validity = [] + for count in range(5): + concrete = dict(years) + concrete[1972] = i.CoverageYear( + OBSERVED, qc_quarters=tuple(n < count for n in range(4)) + ) + try: + result = i.insured_status( + person, concrete, month, test=i.InsuredTest.FULLY + ) + except i.InvalidFamilyInput: + concrete_validity.append(False) + else: + concrete_validity.append(True) + assert result.fully.insured + assert result.current_disability_period_start == date(1973, 1, 1) + assert concrete_validity == [True, False, False, False, False] + _retained_row( + person, + years, + month, + i.InsuredTest.FULLY, + reason=i.InsuredUnsupportedReason.UNKNOWN_EARNINGS, + ) + + +def test_short_dib_entitled_prior_period_keeps_unknown_history_refusal(): + """Reviewer's ALS-waiver filling defeats a five-month emptiness proof.""" + person, years, month = _short_period_case() + with pytest.raises(i.InsuredConfigurationUnsupported) as error: + i.insured_status(person, years, month, test=i.InsuredTest.FULLY) + assert error.value.reason is i.InsuredUnsupportedReason.UNKNOWN_PERIODS + + +def test_short_dib_entitled_unknown_history_keeps_one_denominator_row(): + person, years, month = _short_period_case() + _retained_row( + person, + years, + month, + i.InsuredTest.FULLY, + reason=i.InsuredUnsupportedReason.UNKNOWN_PERIODS, + ) + + +@pytest.mark.parametrize( + "ending", [date(2028, 10, 31), date(2028, 11, 30), date(2028, 12, 31)] +) +def test_short_dib_entitled_concrete_prior_period_is_valid(ending): + person, years, month = _short_period_case() + filled = replace( + person, + prior_disability_periods_provenance=OBSERVED, + prior_disability_periods=( + i.DisabilityPeriod(date(2028, 10, 1), ending), + ), + ) + result = i.insured_status(filled, years, month, test=i.InsuredTest.FULLY) + assert result.fully.insured + assert result.fully.required == 6 + assert result.fully.qc_count_lower == result.fully.qc_count_upper == 6 + assert result.current_disability_period_start == date(2029, 1, 15) + row = _retained_row(filled, years, month, i.InsuredTest.FULLY) + assert row.supported + assert row.result == result + + +def test_pre1956_established_period_retains_automatic_specialist_refusal(): + person, years, month = _pre1956_case() + with pytest.raises(i.InsuredConfigurationUnsupported) as error: + i.insured_status(person, years, month, test=i.InsuredTest.DISABILITY) + assert ( + error.value.reason is i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956 + ) + + +@pytest.mark.parametrize("test", list(i.InsuredTest)) +@pytest.mark.parametrize("unknown_prior", [False, True]) +def test_pre1956_established_period_retains_denominator_for_every_request( + test, unknown_prior +): + person, years, month = _pre1956_case(unknown_prior=unknown_prior) + _retained_row( + person, + years, + month, + test, + reason=i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956, + ) + + +@pytest.mark.parametrize("test", list(i.InsuredTest)) +@pytest.mark.parametrize("unknown_prior", [False, True]) +def test_pre1956_unknown_establishment_cannot_remove_denominator( + test, unknown_prior +): + person, years, month = _pre1956_case( + established=None, unknown_prior=unknown_prior + ) + row = _retained_row(person, years, month, test) + if row.unsupported is not None: + assert row.unsupported.reason in { + i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956, + i.InsuredUnsupportedReason.UNKNOWN_CURRENT_PERIOD, + i.InsuredUnsupportedReason.UNKNOWN_PERIODS, + } + else: + # The direct-QC record is fully insured even without a freeze. + assert test is i.InsuredTest.FULLY + assert row.result.fully.insured + + +@pytest.mark.parametrize("condition", list(i.CoverageCondition)) +def test_flagged_specialist_route_precedes_ordinary_establishment_rejection( + condition, +): + person, years, month = _pre1956_case() + person = replace(person, conditions=(condition,)) + _retained_row( + person, + years, + month, + i.InsuredTest.ALL, + reason=i.InsuredUnsupportedReason[condition.name], + ) + + +def test_unresolved_railroad_compensation_retains_independent_flagged_route(): + """Unreported pre1978 RR compensation can establish a freeze (.350).""" + person = i.Person( + date(1930, 2, 2), + disability_onset=date(1952, 7, 15), + conditions=(i.CoverageCondition.RAILROAD_CREDITS,), + prior_disability_periods_provenance=OBSERVED, + current_disability_period_established=True, + current_disability_period_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + month = date(1968, 2, 1) + years = history(person, month) + # Ordinary wages are observed; the separately flagged RR compensation + # is unresolved. This is not a declaration of final credited QCs. + years[1950] = i.CoverageYear(OBSERVED, quarterly_wages=(Fraction(0),) * 4) + _retained_row( + person, + years, + month, + i.InsuredTest.ALL, + reason=i.InsuredUnsupportedReason.RAILROAD_CREDITS, + ) + + +@settings(max_examples=6, deadline=None) +@example(ending_year=1959, extra=0) +@given(ending_year=st.integers(1959, 1960), extra=st.integers(0, 2)) +def test_unknown_prior_history_preserves_pre1956_alternate_prior_start( + ending_year, extra +): + """An earlier specialist freeze may rescue an ordinary later start. + + Current medical onset is after 1955, so checking only the current + onset for the alternate test cannot prove the prior history empty. + The earlier period satisfies the independently pinned RS .480 test. + """ + person, _, month = _pre1956_case(unknown_prior=True) + person = replace(person, disability_onset=date(1964, 7, 15)) + years = history( + person, + month, + { + 1938: 4, + 1939: 4, + 1940: 4, + 1941: 2, + 1951: 4, + 1952: 2, + 1961: 4, + 1962: 4, + 1963: 4, + 1964: 2 + extra, + }, + ) + filled = replace( + person, + prior_disability_periods_provenance=OBSERVED, + prior_disability_periods=( + i.DisabilityPeriod(date(1952, 7, 15), date(ending_year, 12, 31)), + ), + ) + concrete = i.insured_status(filled, years, month, test=i.InsuredTest.FULLY) + assert concrete.fully.insured + assert concrete.current_disability_period_start == date(1964, 7, 15) + _retained_row(person, years, month, i.InsuredTest.FULLY) + assert _retained_row(filled, years, month, i.InsuredTest.FULLY).supported + + +@settings(max_examples=18, deadline=None) +@example(route="short_dib", ending_month=12, earlier=14, flag=None) +@example(route="pre1956", ending_month=10, earlier=14, flag=None) +@example( + route="flagged", + ending_month=10, + earlier=14, + flag=i.CoverageCondition.RAILROAD_CREDITS, +) +@given( + route=st.sampled_from(["short_dib", "pre1956", "flagged"]), + ending_month=st.integers(10, 12), + earlier=st.integers(14, 16), + flag=st.one_of(st.none(), st.sampled_from(list(i.CoverageCondition))), +) +def test_invalid_declaration_has_no_short_or_specialist_valid_filling( + route, ending_month, earlier, flag +): + """One-way soundness includes short entitlement and specialist routes. + + A valid short DIB-entitled filling is checked through the public rule. + For the pre1956 fillings, the independent RS .480 criterion supplies + 20 total QCs and all six preceding 1951Q1--1952Q2 QCs. A named + specialist refusal therefore represents a possible declaration rather + than evidence that every filling is invalid. Explicit flags retain + their own refusal, including when the ordinary predicate fails. + """ + possible = [] + if route == "short_dib": + import calendar + + person, years, month = _short_period_case() + end = date( + 2028, ending_month, calendar.monthrange(2028, ending_month)[1] + ) + fillings = [ + replace(person, prior_disability_periods_provenance=OBSERVED), + replace( + person, + prior_disability_periods_provenance=OBSERVED, + prior_disability_periods=( + i.DisabilityPeriod(date(2028, 10, 1), end), + ), + ), + ] + requested = i.InsuredTest.FULLY + else: + person, years, month = _pre1956_case( + unknown_prior=True, earlier=earlier + ) + if route == "flagged": + flag = flag or i.CoverageCondition.MILITARY_CREDITS + person = replace(person, conditions=(flag,)) + fillings = [ + replace(person, prior_disability_periods_provenance=OBSERVED) + ] + requested = i.InsuredTest.DISABILITY + assert sum(sum(row.qc_quarters or ()) for row in years.values()) >= 20 + assert years[1951].qc_quarters == (True,) * 4 + assert years[1952].qc_quarters[:2] == (True,) * 2 + possible.append(True) + + invalid = False + try: + i.insured_status(person, years, month, test=requested) + except i.InvalidFamilyInput: + invalid = True + except i.InsuredConfigurationUnsupported: + pass + for filled in fillings: + try: + i.insured_status(filled, years, month, test=requested) + except i.InvalidFamilyInput: + possible.append(False) + except i.InsuredConfigurationUnsupported as refusal: + if route != "short_dib": + assert refusal.reason in { + i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956, + *( + i.InsuredUnsupportedReason[c.name] + for c in person.conditions + ), + } + possible.append(True) + else: + possible.append(True) + if invalid: + assert not any(possible) + if any(possible): + assert not invalid + + +def test_short_entitlement_and_specialist_premises_are_captured(): + act = source_text("lii_usc_42_416") + assert ( + "or such individual was entitled to benefits under section 423 of this title for one or more months in such period" + in act + ) + waiting = source_text("ecfr_20cfr404_315") + assert ( + "You have been medically determined to have amyotrophic lateral sclerosis" + in waiting + ) + alternate = source_text("poms_rs_00301_480") + assert ( + "the wage earner had at least 20 quarters of coverage (QC) by the end of that quarter;" + in alternate + ) + assert ( + "all quarters beginning with 03/51 up to (but not including) that quarter are QCs and there are at least six such QCs." + in alternate + ) + railroad = source_text("poms_rs_00301_350") + assert ( + "We may also use compensation in determining the number of QCs in freeze cases, regardless of entitlement to, or eligibility for an RR annuity." + in railroad + ) diff --git a/tests/test_track_b_insured_status_period_declarations.py b/tests/test_track_b_insured_status_period_declarations.py index 2569222d0..7a761c1f2 100644 --- a/tests/test_track_b_insured_status_period_declarations.py +++ b/tests/test_track_b_insured_status_period_declarations.py @@ -31,6 +31,7 @@ def test_established_current_period_with_unknown_prior_periods_uses_bounds(): assert result.unknown_facts == ( "prior_disability_periods", "current_disability_period_start", + "current_disability_period_end", ) assert result.decided_despite_unknowns disability = i.insured_status( diff --git a/tests/tier_counts.json b/tests/tier_counts.json index 64990a3f9..d15067a23 100644 --- a/tests/tier_counts.json +++ b/tests/tier_counts.json @@ -1,7 +1,7 @@ { "schema_version": 1, "counts": { - "unit": 20440, + "unit": 20493, "artifact": 4271, "integration_psid": 1471, "reproduction_legacy": 520, From 2ae76db2719504e9f9d6551d3370a25d99e4a927 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sat, 31 Oct 2026 10:36:30 -0400 Subject: [PATCH 10/46] Classify impossible insured declarations exactly (#562 round 5) Sol's round-4 review found two mediums and a low: - A later upper-credit witness made every declaration look possible, even when each filling starts after a fixed declared end. The ordinary possibility check now bounds the insured start by the declared end, continuity date and death, and one filling must clear both that bound and any prior-period overlap (20 CFR 404.320(b)(2), 404.321(a), 404.110(b)(1)). An enumeration property compares the predicate with every concrete filling in both directions. - RS 00301.102 B.3.b's wrong-number SS-5 exemption raised a false conflict. An adjudicated exemption now overrides the date-derived presumption. A pre-2004 assignment that declares section 211 applicable stays an input error, and so does an exemption declared by an alien worker born in 2004 or later. - A caller could not say a period was still running. A dated, provenance-bearing continues-through fact now removes earlier endings without supplying one. The new fields follow every existing Person field, so positional arguments keep their meaning. The audit behind this round also applied the same horizon to the RS 00301.480 pre-1956 route. Above 4,096 overlap fillings the predicate refuses by name. Tier counts add this round's 92 unit tests to the three-way sum; the coordinator's slot recount replaces them. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 246 ++++++++++-- .../track_b_insured_status_mutations.json | 218 +++++++++- .../track_b/insured_status.py | 191 +++++++-- tests/README-tiers.md | 4 +- ...b_insured_status_fix_round_5_continuity.py | 223 +++++++++++ ..._insured_status_fix_round_5_possibility.py | 372 ++++++++++++++++++ ...track_b_insured_status_fix_round_5_sspa.py | 245 ++++++++++++ tests/tier_counts.json | 2 +- 8 files changed, 1429 insertions(+), 72 deletions(-) create mode 100644 tests/test_track_b_insured_status_fix_round_5_continuity.py create mode 100644 tests/test_track_b_insured_status_fix_round_5_possibility.py create mode 100644 tests/test_track_b_insured_status_fix_round_5_sspa.py diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index 2644b725c..f8ca3ccf2 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -63,14 +63,24 @@ required for pre-January-2-1913 cohorts), optional `death_date`, optional entitlement). Supplied entitlement months must be within the lifetime and no later than the query. An SSN assignment cannot precede birth. An alien worker may supply an assignment date or `ssn_never_assigned=True`; -supplying both is an input error. These legacy facts derive known section -214(c) applicability. Alternatively the caller declares `sspa211_applies` -with `sspa211_provenance` and optional `sspa211_convention_id`. Applicability +supplying both is an input error. These legacy facts derive section +214(c) applicability unless an adjudicated exemption applies. The caller +declares that determination with `sspa211_applies`, +`sspa211_provenance`, and optional `sspa211_convention_id`. Applicability is decided before the additional requirement is tested. RS 00301.102 B.1 exempts workers whose first SSN was assigned before January 1, 2004, including nonwork SSNs. B.3 expressly includes workers not yet assigned an -SSN in their true identity. B.4.b permits specified work-authorized workers -without an SSN to meet the requirement; it does not exempt all unassigned +SSN in their true identity. B.3.b also exempts a wrong-number SS-5 worker +who could legitimately have received an SSN before 2004. An observed or +convention-filled exemption therefore overrides the post-2003 or +never-assigned presumption, including before a proper true-identity SSN +has been assigned. The worker must have been born before January 1, 2004: +no legitimate pre2004 assignment is possible before birth. An alien born +on or after that date cannot declare an exemption, even without a supplied +assignment date. An actual pre-2004 assignment with declared +applicability remains contradictory because B.1 expressly exempts it. +B.4.b permits specified work-authorized workers without an SSN to meet +the requirement; it does not exempt all unassigned workers. Known applicability retains the named unimplemented SSPA 211 adjudication refusal. Unknown applicability returns a QC-only uninsured answer when it is false either way, flagged as decided despite unknowns; @@ -93,7 +103,7 @@ caller must explicitly declare `current_disability_period_provenance` and `current_disability_period_established`: `True` or `False` for known facts, or `None` with explicit `UNKNOWN`. Omitting this declaration is an input error. `current_disability_period_convention_id` accompanies a convention. -The same canonical `EarningsProvenance` enum applies to all three factual +The same canonical `EarningsProvenance` enum applies to these factual declarations: `OBSERVED`, `CONVENTION_FILLED` with a nonempty identifier, or `UNKNOWN` without a value. The rule supplies no convention internally. @@ -106,12 +116,26 @@ administrative facts. A known established period with no possible insured disabled quarter is invalid. Its start is derived from the supplied QC history, then its years are excluded like any other established period. Every fact-pattern establishment rejection uses one possibility check -across the ordinary route, automatically observable specialist routes, and declared -`CoverageCondition` routes. This check deliberately over-approximates: an -unresolved specialist possibility retains its named refusal. Only when all -routes are impossible can the rule raise `InvalidFamilyInput` before any -coverage refusal. On the ordinary supported QC surface, fewer than six -maximum feasible lifetime QCs proves impossibility: 404.130(a) requires +across the ordinary route, automatically observable specialist routes, +and declared `CoverageCondition` routes. An unresolved specialist +possibility retains its named refusal. The automatically observable +alternate-pre1956 scan independently obeys the same immutable start +horizon: an ending or continuity observation before July 1952 cannot be +rescued by its first permitted July 1, 1952 start (RS .480 B.1). Explicit +specialist declarations remain separately preserved. On the ordinary route, a valid +filling must supply one insured start that is at or before the declared +administrative end and clears every prior-period overlap. A later witness +at the query cannot rescue an immutable earlier end. The scan therefore +stops at that end, any continuity observation, death, or FRA cap, whichever +is earlier. Maximum credits decide the monotone insured-by-that-date +question. If that representative's derived start overlaps a prior period, +the rule checks lower-credit fillings and, when needed, enumerates the +bounded concrete fillings for a single valid period. It never combines +the end compliance of one filling with the overlap compliance of another. +Only when all routes and feasible fillings are impossible can the rule +raise `InvalidFamilyInput` before any coverage refusal. On the ordinary +supported QC surface, fewer than six maximum feasible lifetime QCs proves +impossibility: 404.130(a) requires fully insured status, and 404.110(b)(1) says, "You need at least 6 QCs but not more than 40 QCs to be fully insured." Period exclusions cannot supply missing credits. That ordinary argument does not adjudicate deemed, @@ -160,11 +184,13 @@ administrative ending date, on the last day of a month, with `current_disability_period_end_convention_id`. A default omitted end stays unknown. These three optional fields append after the original twenty `Person` -fields, preserving the existing positional facts as well as keyword calls. +fields. Round 5 appends three continuity fields after all twenty-three +existing fields, preserving every existing positional argument. With an UNKNOWN ending, the rule evaluates every candidate end quarter from -the derived period's start through the last quarter allowed by the query -and FRA/death cap. It additionally considers continuation past the query -when the cap permits. Quarter representatives suffice because exclusions, +the derived period's start, restricted by any continuity observation, +through the last quarter allowed by the query and FRA/death cap. It +additionally considers continuation past the query when the cap permits. +Quarter representatives suffice because exclusions, credited endpoints, and elapsed-year freezes change only at quarter/year boundaries. It does not decide which candidates an administrative record would establish. Continuous medical disability supplies no administrative @@ -182,6 +208,24 @@ envelopes rather than inventing a concrete current period for enumeration. A supplied date retains the existing declaration semantics; known ending provenance requires that date. +An observed running period instead uses +`current_disability_period_continues_through: date | None`, with +`current_disability_period_continues_through_provenance` (default +`UNKNOWN`) and optional +`current_disability_period_continues_through_convention_id`. The same +provenance/value and convention-identifier contracts apply. This fact +requires an established period and says only that it was still in force +on that date. The date cannot precede onset or the possible insured start, +exceed the month-before-FRA cap or death, or follow a declared end. It may +follow the query. Candidate administrative ends must be on or after the +observation; the observation never becomes an end or a credited endpoint. +The caller still receives an UNKNOWN-end disclosure when no actual end +is declared. B6a, OP8(d), and OP12 should use these continuity fields for a +known running cash-benefit or no-cash disability freeze, rather than +inventing a future end. Continuity within the query quarter can leave its +endpoint ambiguous; continuity into a later quarter proves that the query +quarter is interior. + Established starts at or after FRA are invalid even if prior history is UNKNOWN, and every supplied prior period is capped at the month before FRA. The standalone requirement helper shares these limits. A start in the FRA attainment month is also invalid because its @@ -316,7 +360,7 @@ coverage is frozen and the search can continue to the quarter before FRA attainment, or death if earlier (RS 00301.148). DLI itself can remain a range when the requested current statuses agree. Unknown future earnings must not be inferred from this range or from a censored result. -With unknown section214(c) applicability, a decided false current status +With unknown section 214(c) applicability, a decided false current status does not prove that the additional fully insured requirement was met at a historical witness (214(c); RS .102). The conservative DLI lower bound is `None`, while the upper bound retains the QC-only date, including any @@ -400,7 +444,7 @@ a subclass of the shared `FamilyConfigurationUnsupported`. | Pre1951 self-employment income | `pre1951_self_employment_unsupported` | | Earnings require an increment after 2027 | `qc_amount_year_unsupported` | | Query before 1968; blind query before 1973; subsequent-special query before May 1983 | `entitlement_before_1968_unsupported`, `blindness_before_1973_unsupported`, `subsequent_special_before_1983_unsupported` | -| More than 4,096 disability-boundary combinations | `disability_boundary_assignments_unsupported` | +| More than 4,096 disability-boundary combinations, or unresolved ordinary-establishment overlap requiring more than 4,096 credit fillings | `disability_boundary_assignments_unsupported` | The round-3 observable-trigger audit covers every `CoverageCondition`. An explicit condition continues to refuse independently of its ordinary @@ -421,7 +465,7 @@ allocation or adjudicate application facts. | Condition | Observable trigger or absent fact | | --- | --- | | `SIMPLIFIED_PRE1951` | Raw 1937–1950 quarterly wages provide an aggregate divided by $400; post1950 upper QCs and the fully insured prerequisite bound whether it could decide status (213(c); 404.110(d); RS .315). UNKNOWN pre1951 years can supply unbounded raw wages and therefore also trigger the refusal. Direct `qc_quarters` declare credited quarters rather than raw wages. The simplified method does not apply to a disability claim. Filing, retroactivity, and section 227 facts remain unmodeled. | -| `DISABILITY_BEFORE_1956` | Medical onset and QCs reveal a possible RS .480 alternative: at least 20 total QCs and every quarter from 1951Q1 through the quarter before a qualifying 1952Q3–1955Q4 candidate quarter at or after onset, with at least six such quarters. Refuse automatically when this could change a failed disability predicate. Application conditions remain unmodeled. | +| `DISABILITY_BEFORE_1956` | Medical onset and QCs reveal a possible RS .480 alternative: at least 20 total QCs and every quarter from 1951Q1 through the quarter before a qualifying 1952Q3–1955Q4 candidate quarter at or after onset, with at least six such quarters. For declared current establishment, that candidate must fit the immutable declared-end/continuity/death/FRA horizon. Refuse automatically when this could change a failed disability predicate. Application conditions remain unmodeled. | | `DEEMED_FULLY_INSURED` | Wages and dates do not identify covered nonprofit employment or veteran status; retain the explicit flag (404.111–.112; RS .106/.107/.470). | | `TRANSITIONAL_INSURED` | Cohort dates alone do not identify the necessary historical benefit/application facts; retain the explicit flag (RS .101's transitional-benefit referrals). | | `RAILROAD_CREDITS`, `MILITARY_CREDITS` | Ordinary covered earnings do not identify railroad or military service and additional credits; retain explicit flags (RS .350; RS .120/.470). | @@ -464,9 +508,12 @@ against callers reaching private Python names or monkeypatching modules. A fact-pattern rejection means every concrete completion is impossible under every potential route. A named refusal remains whenever an ordinary, automatically observable specialist, or flagged specialist route could -validate the declaration. The common possibility predicate deliberately -admits extra candidates; absence of an ordinary witness alone is no proof -against a specialist route. This distinction also applies when the caller +validate the declaration. Absence of an ordinary witness alone is no proof +against a specialist route. Conversely a later ordinary witness cannot +make an impossible declared end valid; validity must hold in a single +concrete filling. Unresolved specialist administration or an explicit +computational limit retains its named refusal. This distinction also +applies when the caller requests a test other than disability: establishment is a fact of the same declaration, not a conclusion restricted to the requested output. @@ -496,11 +543,12 @@ to a statutory sentence that does not state it. | I3. An established period must start before its FRA-ending boundary, including no start in the FRA month; all supplied prior periods are capped at the preceding month end. | A216(i)(2)(B): "no such period shall begin ... after such individual attains retirement age"; (D)(i) ends at "the month preceding the month" of FRA. C321(a), (c)(1) say the same. A start after the mandatory month-end is impossible under both clauses, including first-day birthdays. The cap supplies no evidence against an earlier UNKNOWN end. | | I4. Supplied prior periods precede the current event/onset and query, do not overlap calendar quarters, and stay within the lifetime. | B404.130(f) refers to "a prior period of disability established for you". C321 gives chronological beginning and ending rules. Nonoverlapping quarter intervals are the declared history representation; specialist credits cannot change what "prior" or a unique represented quarter means. A known overlap is invalid, but overlap between a supplied prior period and a start derived in one UNKNOWN-earnings representative cannot disprove other fillings with a later nonoverlapping start. UNKNOWN history is not treated as supplied empty history. | | I5. A supplied `special_insured` prior period begins before the age-31 attainment quarter. | B404.130(d)(1): a prior period "began before age 31" and the worker "were only insured under paragraph (c)"; (c)(1) requires age 31 not yet attained. A216(i)(3)(B)(iii) expressly uses "before the quarter" of age 31. The flag declares this particular adjudicated young-worker route, not every possible special credit regime. | -| I6. Conflicting SSPA applicability declarations, both never-assigned and an assigned SSN, or assignment before birth are invalid. | RS .102 B.1 distinguishes "first assigned on or after January 1, 2004" from an earlier first assignment; B.3 says "or if they have not yet been assigned an SSN based on their true identity". Mutually contradictory declarations cannot be repaired by a visa/work-authorization route. Meeting the additional requirement is distinct from exemption. | +| I6. An alien worker's actual pre2004 SSN assignment conflicts with declared SSPA applicability; birth on/after January 1, 2004 conflicts with declared exemption. Both never-assigned and an assigned SSN, or assignment before birth, remain invalid. A worker born before 2004 may pair a post2003 assignment or never-assigned status with an adjudicated exemption. | RS .102 B.1 says an alien assigned an SSN before 2004 "is exempt", including a nonwork SSN. B.3.b says, "If an alien worker could have legitimately been assigned an SSN before 1/1/2004, the worker is exempt from the requirements of section 211 of the SSPA." Its wrong-number SS-5 scenario issued another person's number "instead of assigning the alien worker their own SSN". Thus observed or convention-filled exemption overrides either later-assignment or never-assigned presumptions when legitimate pre2004 assignment was possible. Birth on/after January 1, 2004 rules out that exception independently of the assignment record. B.4.b's worker without an SSN "is nevertheless considered to meet the work SSN requirement" when work-authorized; meeting that requirement alone supplies no exemption. | | I7. Explicit quarterly QCs or positive quarterly wages cannot occur before birth, after the query/coverage-end quarter, or after the death quarter. Every required coverage year is declared exactly once through the earliest query, exit, or death year. | A213(a)(2)(B)(i), (v): "no quarter after the quarter in which an individual dies" and "no quarter shall be counted ... prior to the beginning of such quarter"; B404.146(a)-(b) agree. Birth and supplied-record exit caps, complete years, and no implicit zeros are interface premises. Annual counts are capped rather than dated after exit. Specialist earned-basis or additional-credit declarations remain refusals and do not reinterpret an explicit ordinary covered-quarter declaration. | -| I8. A declared current establishment with no possible insured start is invalid only after the shared possibility check excludes every route and every feasible prior/earnings filling. | C320(b)(2) requires insured disability "in the calendar quarter in which you became disabled, or in a later calendar quarter"; C321(a) chooses the first such quarter. B404.130(a) says "four different rules"; RS .480 supplies an additional historical test with "at least 20 quarters of coverage" and every qualifying 1951 quarter. Flagged routes and automatically detected alternatives defeat an ordinary-only impossibility proof. An UNKNOWN-credit representative that places the first insured start after a declared end does not exclude a different credit filling with an earlier valid start; even upper-credit construction failure is not proof if an ordinary insured candidate remains possible. In particular, its derived start may overlap a prior quarter while a lower-credit filling starts later without overlap. | +| I8. A declared current establishment with no possible insured start is invalid only after the shared possibility check excludes every route and every feasible prior/earnings filling. One ordinary filling must satisfy the start, declared end, continuity, and overlap constraints together. | C320(b)(2) requires insured disability "in the calendar quarter in which you became disabled, or in a later calendar quarter"; C321(a) chooses the first such quarter. B404.130(a) says "four different rules"; RS .480 supplies an additional historical test with "at least 20 quarters of coverage" and every qualifying 1951 quarter. Independent flagged and automatic guards preserve those routes; the automatic pre1956 scan obeys the same immutable starting horizon. The ordinary scan is capped by the declared end and continuity date as well as query/death/FRA. Maximum credits decide whether insurance by that fixed date is possible. A failure caused by a derived prior-quarter overlap instead requires a lower-credit or enumerated filling with a nonoverlapping first start by the same cap. A witness after the declared end never supplies possibility. | | I9. Fewer than six maximum feasible ordinary lifetime QCs proves current establishment impossible only when all specialist possibilities have already been excluded. | B404.110(b)(1): "You need at least 6 QCs but not more than 40 QCs"; B404.130(a): "you must be fully insured". B404.110(a) separately names deemed veteran/nonprofit routes, and RS .131/.350 cover other credits. Those alternatives prevent applying the ordinary six-QC input-error proof to a potentially valid specialist declaration. A record composed entirely of direct final QC declarations (`qc_count` or `qc_quarters`) and UNKNOWN years already fixes or bounds all admissible QCs, including RR credits, so the RR flag cannot add quarters beyond that envelope. This is the direct-credit input contract, not a claim that ordinary RSDI credits always exhaust freeze credits: RS .131 expressly allows credits "not creditable for other" purposes. If earnings allocation or that final-credit declaration is unresolved, the RR route remains possible; RS .230 and .350 supply annual and historical RR credit rules. Period exclusions alone cannot add ordinary QCs. | | I10. The supported calendar, mandatory historical sex, and explicit establishment declaration must be supplied: birth years 1870–9900, query years through 9990, sex for births before January 2, 1913, and establishment provenance whenever onset is present. | These are interface-domain requirements. B404.110(b)(2) and .132 apply different historical male/female endpoints; B404.110(c) excludes only a period "we established for you". Missing facts are not inferred. Calendar limits reserve space for date arithmetic and assert no legal incapacity outside the implementation domain; alternative credit routes cannot supply missing declared facts. | +| I11. A continues-through observation requires established disability, cannot precede medical onset or the first feasible insured start, cannot exceed the pre-FRA or death boundary, and cannot follow a declared administrative end. | C320(b)(2) and C321(a) require the insured start; A216(i)(2)(D) and C321(c) bound the period's end. A declaration that a period was in force on a date requires that date to lie within one possible period. This is a dated observation, not an asserted ending; a date later than the query is allowed. Provenance and convention identifiers follow the existing fact schema. | | ID and UNKNOWN collapse | Captured text and alternative-route defense | | --- | --- | @@ -508,19 +556,20 @@ to a statutory sentence that does not state it. | U2. UNKNOWN current establishment needs no new-period alternative if there is no medical onset or onset is at/after the statutory latest starting month. | A216(i)(2)(A)-(D) and C321 prohibit a period without disability or a nonempty pre-FRA interval. This removes an impossible new-period alternative only; it does not remove UNKNOWN prior history or an existing period's UNKNOWN administrative end. | | U3. With unknown prior/current periods, true ordinary status under favorable all-period disregard decides true. | C320(a): "If benefits ... would be denied or reduced because of a period of disability, the period of disability will not be taken into consideration." B404.130(f) also permits counting all prior quarters if favorable. RS .120 requires all periods used or all disregarded; selective exclusions are not assumed. Specialist credit regimes are refused first. | | U4. With unknown periods, fewer than six maximum feasible QCs decides false only on the ordinary route after specialist possibilities are excluded. | B404.110(b)(1) and B404.130(a) supply the six-QC prerequisite. U3's disregard cannot manufacture credits. Deemed, transitional, foreign, military/railroad, and automatically revealed historical alternatives retain named refusals instead of using this ordinary collapse. | -| U5. UNKNOWN earnings decide a requested Boolean only if all lower/upper ordinary earnings witnesses agree, under the permitted fixed-period/all-period treatments; an uncertain established start refuses. | B404.143 credits one QC for each increment, maximum four; B404.130 and .146 supply assignment/exclusion rules. Adding ordinary QCs cannot invalidate a fixed treatment. A derived start cannot be silently held fixed when the completion changes it. If a lower or upper representative cannot construct the declared period, including a derived overlap with a supplied prior period, but another UNKNOWN-credit filling can, the public result is `unknown_earnings_years_decide_status`, not an input error. Specialist possibilities and administrative-end candidates are considered separately, so the endpoint argument is never used to exclude them. | -| U6. UNKNOWN administrative end decides a status only when every end-quarter candidate from start through query/cap, plus permitted continuation, agrees. | A216(i)(2)(D) uses "whichever ... is the earlier"; C321(c)(3) includes "the last month for which you received benefits" after substantial gainful activity. Medical continuity cannot exclude early ends. FRA/death caps limit the latest candidate and do not turn the unknown into a fact. Both ending and prior-history unknown facts remain disclosed when both are missing; UNKNOWN prior history uses the universal envelopes rather than inventing a derived current period to enumerate. An actual supplied end keeps its declared-date semantics; known ending provenance requires an ending date. | +| U5. UNKNOWN earnings decide a requested Boolean only if all lower/upper ordinary earnings witnesses agree, under the permitted fixed-period/all-period treatments; an uncertain established start refuses only after at least one feasible filling survives. | B404.143 credits one QC for each increment, maximum four; B404.130 and .146 supply assignment/exclusion rules. Adding ordinary QCs cannot invalidate a fixed treatment. A derived start cannot be silently held fixed when the completion changes it. If a lower or upper representative cannot construct the declared period, but another single filling meets its end, continuity, and prior-overlap constraints, the public result is `unknown_earnings_years_decide_status`. If no ordinary filling can qualify by the declared end and all independent routes are impossible, it is an input error and creates no row. Specialist possibilities and administrative-end candidates are considered separately. | +| U6. UNKNOWN administrative end decides a status only when every end-quarter candidate from start through query/cap, plus permitted continuation, agrees, after applying any continuity lower bound. | A216(i)(2)(D) uses "whichever ... is the earlier"; C321(c)(3) includes "the last month for which you received benefits" after substantial gainful activity. Medical continuity cannot exclude early ends; a dated administrative continuity observation can. FRA/death caps limit the latest candidate and do not turn the unknown into a fact. Both ending and prior-history unknown facts remain disclosed when both are missing; UNKNOWN prior history uses the universal envelopes rather than inventing a derived current period to enumerate. An actual supplied end keeps its declared-date semantics; known ending provenance requires an ending date. | | U7. UNKNOWN SSPA applicability preserves an ordinary QC-only false status, but never a QC-only true status. | RS .102 B.2 says the worker "must meet one of the following additional requirements" and may fail "even if" the QC requirement is met. Applicability can remove ordinary insurance and cannot supply missing QCs. Known applicability retains adjudication refusal; any separate specialist path is refused first. | | U8. With UNKNOWN prior history, a known current period's start is certain onset only if the lower-credit favorable-disregard witness already insures at onset; otherwise the start stays unknown. | A216(i)(2)(C) and C321(a) make insured onset the earliest legal start. C320(a)'s disregard permits that witness, and no route can move this period before medical onset. Other potentially valid histories prevent an impossibility error but do not fabricate a start. | +| U9. A continues-through observation removes only candidate administrative ends before its date; it never supplies an ending endpoint or removes UNKNOWN-end disclosure. | C321(c) enumerates actual ending events. Observation of a period still in force supplies a lower bound on those events, not their occurrence. Same-quarter ends remain possible, while a later-quarter observation makes the query quarter interior. | | ID and bound | Captured text and alternative-route defense | | --- | --- | | B1. UNKNOWN annual ordinary QCs range from zero through four, reduced by assignable birth/query/death/exit quarters. Exact annual amounts are monotone in earnings; every calendar year stays in 0–4. | B404.143: "we cannot credit you with more than four QCs for any calendar year"; A213(a)(2)(B)(vi) prohibits duplicate calendar-quarter QCs; B404.146 excludes unbegun/death quarters. Birth/exit are supplied-record premises. Additional-credit regimes retain refusal and cannot escape this bound through an ordinary result. | | B2. Ordinary fully insured requirements lie in 6–40 and exclude only established disability years. Every elapsed-year endpoint uses its relevant candidate year and the historical sex/cohort rule. | B404.110(b)(1), (b)(2), (c), .132; A214(a) says "not counting ... any year any part of which was included in a period of disability". Medical onset without establishment cannot freeze years. Deemed/transitional alternatives are refused before using the ordinary requirement as universal. | | B3. A simplified-pre1951 possibility uses the smallest known freeze requirement, or six for unresolved establishment/history, and maximum post1950 ordinary credits without exclusions. UNKNOWN pre1951 raw wages remain potentially decisive. | A213(c) grants "one quarter of coverage for each $400" subject to resulting fully insured status; B404.110(c)-(d); RS .315 B.1-B.2 record alternate historical/application conditions. This is an over-approximation for refusal, not a computed deemed-credit answer. A favorable ordinary witness with a higher requirement cannot narrow it. | -| B4. An alternate-pre1956 possibility uses maximum feasible QCs and any eligible 1952Q3–1955Q4 quarter with at least 20 total QCs and every preceding 1951-onward quarter credited, minimum six. | RS .480 A requires "at least 20 quarters of coverage" and "all quarters beginning with 03/51 ... are QCs" with "at least six"; B.1 gives first freeze day 07/01/52 and last 12/31/55. Unmodeled application restrictions can only remove candidates, so they cannot justify an input error. Flagged specialist routes also preserve possibility. | +| B4. An alternate-pre1956 possibility uses maximum feasible QCs and any eligible 1952Q3–1955Q4 quarter with at least 20 total QCs and every preceding 1951-onward quarter credited, minimum six. Current establishment also requires that quarter to fit every fixed starting bound. | RS .480 A requires "at least 20 quarters of coverage" and "all quarters beginning with 03/51 ... are QCs" with "at least six"; B.1 gives first freeze day 07/01/52 and last 12/31/55. The first possible freeze day is July 1, 1952; an established current period already ended, or observed in force, before then cannot use a later automatic witness. The automatic scan shares the ordinary immutable end/continuity/death/FRA horizon. Unmodeled application restrictions can only remove candidates, so they cannot justify an input error. Explicit specialist flags remain independent possibilities. | | B5. Universal recent, fully-prerequisite, and annual count envelopes use zero through maximum feasible ordinary lifetime/year QCs whenever unknown periods/earnings can switch witnesses. | A213(a)(2)(B)(vi) prohibits double credit; B404.146(d) excludes interiors unless disregarded. Every concrete ordinary assignment is a subset of feasible unique lifetime quarters. The envelope permits every witness, even when adding QCs switches to a lower-count witness. Specialist possibilities remain refusals. | -| B6. With known earnings and an UNKNOWN ending, returned count bounds include all end-candidate counts; with entirely known facts they remain exact. | B404.120(b), .130(f), .146(d) distinguish credited endpoints and excluded interiors. All candidate quarters are enumerated, including early endpoints and capped-FRA candidates; extrema therefore cover each completion. No monotonic endpoint-count premise is used. | +| B6. With known earnings and an UNKNOWN ending, returned count bounds include all end-candidate counts admitted by continuity; with entirely known facts they remain exact. | B404.120(b), .130(f), .146(d) distinguish credited endpoints and excluded interiors. All candidate quarters are enumerated, including early endpoints and capped-FRA candidates, subject to any continues-through observation; extrema therefore cover each completion. A continuity date is never inserted as a credited endpoint. No monotonic endpoint-count premise is used. | | B7. DLI lies through query without frozen exit, or through the pre-FRA-quarter/death horizon with frozen coverage; `None` is the bottom bound. A future exit cannot remove query censoring. | RS .148 defines DLI as "the last day in the last quarter" in which status is met and limits the search relative to FRA. B404.146(b) caps credits after death; A216(i)(2)(B) caps new periods. Future undeclared work is not assumed zero. Specialist routes are refused before this ordinary DLI calculation. | | B8. For a nonblind ordinary worker with no prior period, no DLI can lie more than 39 quarters after the last credited quarter. | B404.130(b)(2) requires "at least 20 QCs in the 40-quarter period ... ending with that quarter". After 39 later quarters no original QC remains. Blindness and prior-period special/exclusion routes disable this search shortcut; flagged or observable specialist routes refuse. | | B9. With unknown periods the disregard DLI is a lower bound and the permitted query/FRA/death horizon is the upper bound; unknown SSPA applicability reduces any positive DLI lower bound to `None`. | C320(a) permits favorable disregard; B404.130(f) permits counting all prior-period quarters; RS .102 B.2 imposes an additional requirement. The bound does not infer a particular recovery or history. Exemption can recover the ordinary upper witness but cannot exceed the calendar horizon. | @@ -528,12 +577,51 @@ to a statutory sentence that does not state it. | B11. At most 4,096 combinations of disability endpoint assignments are searched exactly. | B404.143(b) and RS .230 permit favorable assignment; B404.130(f) makes endpoint credits decisive. The limit is computational coverage, not a statutory impossibility bound: exceeding it returns `disability_boundary_assignments_unsupported`, never a false status or input error. | | B12. Ordinary counted windows have 13 quarters for current insurance and 40 for ordinary disability; young/subsequent special windows require half their elapsed quarters after dropping an odd remainder, with a six-QC minimum and 20/40 ceiling. | B404.120(a) says "13-quarter period"; .130(b) says "20 QCs in the 40-quarter period"; .130(c)-(d) and A216(i)(3)(B) supply the half-quarter, odd-remainder, and 6/12 alternatives. Blindness uses only the fully insured prerequisite, and pre1956/flagged specialist paths retain refusal rather than being forced through an ordinary window. | | B13. Indexed annual QC amounts are at least the prior year's statutory increment and the rounded indexed 1978 amount, with nearest-$10 rounding and $5 ties upward. | A213(d)(2) chooses "the larger of" the prior increment and indexed amount, rounded to "the next higher multiple of $10" at a $5 tie. This exact parameter calculation has no disability or specialist alternative; input-domain checks require positive NAWI and a statutory prior increment. | - -The round-4 adversarial audit revisits each row's alternatives in the final -report. The three new source-mandated counterexamples are short -DIB-entitled periods (U1), early administrative endings including FRA -(U6/B6/B10), and the alternate pre1956 establishment route (I8/I9/B4). -None is an unresolved statutory reading. +| B14. Declaring continuity never widens the administrative-end candidate set; every returned status and count envelope remains valid for every retained concrete ending. | C321(c)'s ending events still govern. Set intersection with ends on/after the observation can only remove candidates; it creates neither an ending nor a new credit. The universal envelope remains unchanged where other unknown facts require it. | +| B15. Ordinary establishment overlap resolution enumerates at most 4,096 unknown-credit fillings after its fixed-date monotonicity check. | C320(b)(2) and C321(a) require one insured beginning consistent with the complete declaration. This is a computational coverage bound. An unresolved search beyond the limit returns `disability_boundary_assignments_unsupported`; it never asserts that a concrete filling exists or proves an input error. | + +The round-5 adversarial audit revisits each row in both directions in +`scratch/review/round5-premise-audit.md`: a valid filling cannot be rejected, +and a provably all-invalid declaration cannot become a denominator row. +The fixed-end counterexamples correct I1/I8/U5 and the automatic historical +cap in B4; the wrong-number SS-5 exception and its required possible pre2004 +assignment correct I6; continuity adds I11/U9/B14. These are source and +interface requirements, with no new statutory reading. + +The round-5 exactness grid checks both directions against every concrete +completion, rather than only checking that rejection is sound. +`test_unknown_declaration_exactly_matches_all_concrete_qc_fillings` +uses one or two UNKNOWN modern years (all five or 25 annual-count +fillings), known counts zero through four, January/March/June/December +ends, and blind/nonblind workers. +`test_overlap_declaration_exactly_matches_every_quarter_filling` uses +four missing-year shapes, prior endings in December 1971 or January 1972, +current endings in March/December 1972 or January 1973, and every one of the +16 pre1978 quarterly masks. The specialist grids retain the automatic +alternate-pre1956 route and every `CoverageCondition`. +`test_exact_classification_keeps_each_independent_flagged_route` also +disables the automatic pre1956 guard, proving that each flag preserves +its route independently; the RR case supplies unresolved pre1978 +compensation rather than a final direct-QC envelope. The short-DIB grid +supplies empty and three one-month prior-history fillings. +Each concrete declaration either raises an input error or survives as a +status/refusal; the UNKNOWN declaration must be invalid exactly when all +concrete fillings are invalid. Every surviving UNKNOWN declaration is +also evaluated to assert one retained row and its exact weight. + +Two corners are excluded by name from this exactness claim. Arbitrary +UNKNOWN prior history is not exhaustively enumerable in this bounded +grid: its earliest-period possibility proof intentionally leaves +unobserved administrative histories unresolved, while the explicit +short-DIB fillings test the retained existential witness. Large unresolved +ordinary-overlap searches above 4,096 credit fillings return the named +computational refusal, as pinned by +`test_large_unresolved_overlap_has_explicit_complexity_refusal`; that +refusal asserts neither existence nor impossibility. Specialist +administrative adjudication is outside the implemented ordinary surface; +the specialist grid checks preservation of a possible route and its +denominator, rather than claiming to adjudicate it. No bounded ordinary +grid case is silently excluded. ## Executed invariants @@ -619,6 +707,78 @@ Round 4 extends those invariants across every statutory alternative: | A valid UNKNOWN-earnings completion with its insured start on/before the declared period end prevents an input error, even if another representative starts after the end; uncertainty retains a refusal and denominator row. | `test_possible_unknown_earnings_filling_prevents_declared_end_input_error` | | A valid lower-credit completion whose derived current start does not overlap a supplied prior period prevents an input error, even if the upper-credit representative overlaps its ending quarter; uncertainty retains a refusal and denominator row. | `test_possible_lower_earnings_filling_prevents_upper_overlap_input_error` | +Round 5 adds exact classification and administrative continuity: + +| Invariant | Hypothesis test | +| --- | --- | +| Over the bounded modern and pre1978 overlap grids, `InvalidFamilyInput` occurs exactly when every concrete credit filling is invalid. A surviving filling prevents rejection, while an all-invalid declaration never acquires an evaluator row. | `test_unknown_declaration_exactly_matches_all_concrete_qc_fillings`, `test_overlap_declaration_exactly_matches_every_quarter_filling` | +| The automatically detected alternate-pre1956 start obeys the same fixed declared-end and continuity bounds as an ordinary start. A bound before July 1952 cannot use the first permitted July 1, 1952 freeze; a later permissible bound preserves the specialist refusal. | `test_automatic_pre1956_start_respects_immutable_bound_property` | +| An automatically detected historical start must fit before the actual month-before-FRA end, including when FRA and the first possible alternate start share July 1, 1952. | `test_automatic_pre1956_start_respects_fra_cap_property` | +| An adjudicated section 211 exemption preserves the ordinary status/count result and one evaluator row for source-permitted post2003 and never-assigned facts; observed and convention-filled facts have equal statutory treatment. Pre2004-assigned aliens accept exactly the exempt declaration and reject declared applicability. An alien born on/after January 1, 2004 cannot supply the required possible pre2004 assignment and therefore cannot declare exemption. | `test_adjudicated_exemption_preserves_ordinary_count_and_evaluator_row`, `test_pre2004_assignment_accepts_exactly_the_exempt_applicability`, `test_wrong_number_exemption_requires_possible_pre2004_assignment` | +| A continuity declaration never widens the candidate-ending set. Every returned status and count envelope agrees with or contains every retained concrete ending; no continuity observation becomes a credited endpoint. | `test_continuity_only_narrows_candidates_and_all_concrete_ends_agree` | + +The fixed-end example has birth February 2, 2000, medical onset January 15, +2022, observed establishment, a January 31, 2022 declared end, four QCs +in 2021, UNKNOWN 2022 credits, and zeros elsewhere. At an April 2022 +FULLY query, only five QCs can be assigned by the end's quarter: four +earlier credits plus 2022Q1. All five concrete 2022 counts fail, so the +UNKNOWN declaration raises `InvalidFamilyInput` through the evaluator; +it cannot contribute a row of weight 3/2. The nine nearby combinations +of two, three, or four 2021 QCs with January, February, or March 2022 +ends fail for the same reason at an October 2022 query. The existing +round-4 lower-filling overlap and earlier-valid-end cases remain valid +UNKNOWN declarations and retain their original numeric assertions. +The overlap grid additionally minimizes an intended valid case: with the +January 1972 prior ending and December 1972 current ending, seven of the +16 UNKNOWN-1972 quarter masks are valid. They leave Q1 uncredited and +credit at least one later quarter, permitting a nonoverlapping insured +start before the fixed end. Both all-zero and all-four representatives +are invalid there, so checking only those representatives would reject a +valid declaration. Moving the declared end to March 1972 instead leaves +all 16 masks invalid; separate fillings cannot each supply half the +chronological constraints. + +The automatic historical-bound counterexample has a woman born February +2, 1900, current onset January 15, 1952, observed establishment and empty +prior history, fourteen older QCs, and six QCs in the mandatory +1951Q1–1952Q2 window. She has twenty lifetime QCs but +fails the ordinary recent-work test. A March or June 1952 declared end, +or a continuity observation in either month, cannot use RS .480's first +permitted July 1, 1952 start. The declaration is therefore input-invalid. +July and September bounds instead preserve the automatic historical +route and its named refusal. This source-required chronological check is +independent of the ordinary possibility scan and of explicit specialist +flags. A woman born July 2, 1887 reaches FRA in July 1952, so her +period's latest end is June 30 and the alternate July 1 start is already +too late. An August 2 birth instead permits that start. This actual +month-before-FRA limit is shared by the ordinary and automatic scans. + +The wrong-number SS-5 example has birth February 2, 1980, alien-worker +status, assignment January 1, 2004, an observed `sspa211_applies=False`, +four QCs in 2004, and two in 2005. FULLY at January 2006 returns insured, +required six, count six. The exemption is an adjudicated input justified +by RS .102 B.3.b, not an inferred exemption for every later assignment. +The never-assigned/exempt pairing is also source-permitted. A declaration +of applicability with a pre2004 assignment remains an input error. The +independent I6 audit also tested birth and assignment January 1, 2005 with an observed +exemption and six QCs at January 2026. That worker cannot have received a +legitimate pre2004 SSN; the input is invalid. The same contradiction holds +at the exact January 1, 2004 birth boundary, with a never-assigned SSN, +or without an assignment declaration. B.4.b's work-authorization route +does not rescue exemption: it satisfies the additional requirement while +retaining applicability. + +The continuity example has birth February 2, 2000, blind onset January +15, 2022, observed current establishment and empty prior history, and QCs +2017=1, 2020=4, 2021=1, 2026=1. At a March 2026 CURRENTLY query, +continuity through March still admits a March 31 end with six QCs and +later endings with five, so the rule refuses by name. Continuity into +April or later makes 2026Q1 interior, yielding uninsured with count five. +With only the six earlier credits, a February 2062 FULLY query and +continuity through that month returns insured, required six, count six; +the rule records an unknown actual ending throughout. These invented +cases compute insurance only, with no benefit-amount claim. + Round-4 example/evaluator regressions separately reproduce the reviewer's short-DIB prior period, early end and FRA-end cases, and automatic pre1956 establishment for every requested test with UNKNOWN prior history @@ -796,8 +956,14 @@ Medical onset versus administrative establishment and the event's own period are corrections required by 416(i)(2), 404.110(c), 404.120(b), and 404.320-.321. The never-assigned-SSN applicability text in RS .102 B.3 also controls over the coordinator's reported blanket exemption; B.4.b's -work-authorized exception concerns satisfying the requirement. Known -applicable cases remain refused until that adjudication is implemented. +work-authorized exception concerns satisfying the requirement. B.3.b's +wrong-number SS-5 exemption separately requires accepting an adjudicated +exemption even with a later actual assignment or no proper assignment +yet, provided pre2004 legitimate assignment was possible. An alien born +on/after January 1, 2004 cannot meet that premise. An actual pre2004 +assignment remains expressly exempt under B.1, +so a declaration that section 211 applies in that pairing stays invalid. +Known applicable cases remain refused until that adjudication is implemented. For simplified pre1951 credits, Act 213(c) says an individual "shall be deemed to have one quarter of coverage for each $400 of his total wages @@ -826,10 +992,10 @@ do not establish that historical entitlement. Conditional on an otherwise payable invented $1,000 monthly benefit, those answers differ by $0 versus $1,000; this module computes neither payment. -Short DIB-entitled periods, earlier administrative endings, and the -alternate pre1956 test are captured source requirements and missing -administrative facts. They introduce no competing reading or additional -question for Max. +Short DIB-entitled periods, earlier administrative endings, the alternate +pre1956 test, and the wrong-number SS-5 exemption are captured source +requirements. Dated observed continuity supplies a missing input; it is +not a new statutory reading. They introduce no additional question for Max. Mutation checks are recorded in [`track_b_insured_status_mutations.json`](track_b_insured_status_mutations.json). diff --git a/docs/design/track_b_insured_status_mutations.json b/docs/design/track_b_insured_status_mutations.json index 51c7048ea..bf8121d31 100644 --- a/docs/design/track_b_insured_status_mutations.json +++ b/docs/design/track_b_insured_status_mutations.json @@ -1866,5 +1866,221 @@ } ], "round_4_note": "Nine implementation mutations were caught in isolated in-memory module namespaces; no mutation was written to the working tree. Final source includes the UNKNOWN-prior concrete-enumeration guard, explicit missing-end disclosure, and sound refusal for invalid lower/upper earnings representatives when a valid completion remains possible. Existing concrete assertions remain; final controls and exact commands are in the fix-round-4 report.", - "round_4_final_source_sha256": "735245b19fce6f2439c222acac2956761032971c8fced8fde2f56d372b2abb95" + "round_4_final_source_sha256": "735245b19fce6f2439c222acac2956761032971c8fced8fde2f56d372b2abb95", + "round_5_mutations": [ + { + "name": "round5_fixed_date_six_qc_boundary", + "before": "if sum(len(_assign_qcs(*row)) for row in rows.values()) < 6:", + "after": "if sum(len(_assign_qcs(*row)) for row in rows.values()) <= 6:", + "failed_tests": [ + "tests/test_track_b_insured_status_fix_round_5_possibility.py::test_six_qcs_by_fixed_end_preserve_valid_unknown_declaration" + ], + "command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/round5-epuf POPULACE_DYNAMICS_PSID_DIR=/nonexistent/round5-psid /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/mutate_round5_possibility.py fixed_date_six_qc_boundary", + "summary": "1 failed in 3.92s; exactly six QCs before the fixed end must retain the valid concrete/UNKNOWN declarations.", + "isolated": true, + "restored": true, + "restoration": "Only inspect.getsource(_could_establish_current_period) was mutated and executed in the canonical module dictionary in an isolated process. The harness never wrote implementation files; process exit discarded the mutant.", + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round5 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round5 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport inspect\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\nsource = inspect.getsource(i._could_establish_current_period)\nbefore = 'if sum(len(_assign_qcs(*row)) for row in rows.values()) < 6:'\nafter = 'if sum(len(_assign_qcs(*row)) for row in rows.values()) <= 6:'\nassert source.count(before) == 1\nexec(compile(source.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', '--tb=short', 'tests/test_track_b_insured_status_fix_round_5_possibility.py::test_six_qcs_by_fixed_end_preserve_valid_unknown_declaration'])\nassert Path(i.__file__).read_text() == original\nraise SystemExit(result)\nPY" + }, + { + "name": "round5_drop_same_filling_period_validation", + "before": "_with_current_period(plain, filling, horizon, exit_month)", + "after": "_decision_witness(plain, filling, horizon, exit_month, InsuredTest.DISABILITY)", + "failed_tests": [ + "tests/test_track_b_insured_status_fix_round_5_possibility.py::test_different_fillings_cannot_separately_satisfy_end_and_overlap" + ], + "command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/round5-epuf POPULACE_DYNAMICS_PSID_DIR=/nonexistent/round5-psid /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/mutate_round5_possibility.py drop_same_filling_period_validation", + "summary": "1 failed in 3.74s; UNKNOWN became a counted refusal even though all16 concrete masks failed the fixed-end/overlap conjunction.", + "isolated": true, + "restored": true, + "restoration": "Only inspect.getsource(_could_establish_current_period) was mutated and executed in the canonical module dictionary in an isolated process. The harness never wrote implementation files; process exit discarded the mutant.", + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round5 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round5 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport inspect\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\nsource = inspect.getsource(i._could_establish_current_period)\nbefore = '_with_current_period(plain, filling, horizon, exit_month)'\nafter = '_decision_witness(plain, filling, horizon, exit_month, InsuredTest.DISABILITY)'\nassert source.count(before) == 1\nexec(compile(source.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', '--tb=short', 'tests/test_track_b_insured_status_fix_round_5_possibility.py::test_different_fillings_cannot_separately_satisfy_end_and_overlap'])\nassert Path(i.__file__).read_text() == original\nraise SystemExit(result)\nPY" + }, + { + "name": "round5_lose_pre1978_quarter_placements", + "before": "if year < 1978:", + "after": "if year < 1937:", + "failed_tests": [ + "tests/test_track_b_insured_status_fix_round_5_possibility.py::test_later_quarter_filling_can_clear_overlap_before_fixed_end" + ], + "command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/round5-epuf POPULACE_DYNAMICS_PSID_DIR=/nonexistent/round5-psid /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/mutate_round5_possibility.py lose_pre1978_quarter_placements", + "summary": "1 failed in 7.29s; annual flexible-count surrogates falsely rejected UNKNOWN despite seven valid later-quarter masks.", + "isolated": true, + "restored": true, + "restoration": "Only inspect.getsource(_could_establish_current_period) was mutated and executed in the canonical module dictionary in an isolated process. The harness never wrote implementation files; process exit discarded the mutant.", + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round5 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round5 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport inspect\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\nsource = inspect.getsource(i._could_establish_current_period)\nbefore = 'if year < 1978:'\nafter = 'if year < 1937:'\nassert source.count(before) == 1\nexec(compile(source.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', '--tb=short', 'tests/test_track_b_insured_status_fix_round_5_possibility.py::test_later_quarter_filling_can_clear_overlap_before_fixed_end'])\nassert Path(i.__file__).read_text() == original\nraise SystemExit(result)\nPY" + }, + { + "name": "round5_lose_automatic_pre1956_bound", + "before": "if person.current_disability_period_established:", + "after": "if False and person.current_disability_period_established:", + "target_function": "_pre1956_alternate_possible", + "failed_tests": [ + "tests/test_track_b_insured_status_fix_round_5_possibility.py::test_automatic_pre1956_start_obeys_fixed_end_and_continuity[bound0-end]", + "tests/test_track_b_insured_status_fix_round_5_possibility.py::test_automatic_pre1956_start_obeys_fixed_end_and_continuity[bound0-continuity]", + "tests/test_track_b_insured_status_fix_round_5_possibility.py::test_automatic_pre1956_start_obeys_fixed_end_and_continuity[bound1-end]", + "tests/test_track_b_insured_status_fix_round_5_possibility.py::test_automatic_pre1956_start_obeys_fixed_end_and_continuity[bound1-continuity]" + ], + "command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/round5-epuf POPULACE_DYNAMICS_PSID_DIR=/nonexistent/round5-psid /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/mutate_round5_possibility.py lose_automatic_pre1956_bound", + "summary": "4 failed, 4 passed in 12.21s; the automatic alternate route must start before declared end or continuity, independently of the ordinary scan.", + "isolated": true, + "restored": true, + "restoration": "Only inspect.getsource(_pre1956_alternate_possible) was mutated and executed in the canonical module dictionary in an isolated process. The harness never wrote implementation files; process exit discarded the mutant.", + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round5 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round5 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport inspect\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\nsource = inspect.getsource(i._pre1956_alternate_possible)\nbefore = 'if person.current_disability_period_established:'\nafter = 'if False and person.current_disability_period_established:'\nassert source.count(before) == 1\nexec(compile(source.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', '--tb=short', 'tests/test_track_b_insured_status_fix_round_5_possibility.py::test_automatic_pre1956_start_obeys_fixed_end_and_continuity[bound0-end]', 'tests/test_track_b_insured_status_fix_round_5_possibility.py::test_automatic_pre1956_start_obeys_fixed_end_and_continuity[bound0-continuity]', 'tests/test_track_b_insured_status_fix_round_5_possibility.py::test_automatic_pre1956_start_obeys_fixed_end_and_continuity[bound1-end]', 'tests/test_track_b_insured_status_fix_round_5_possibility.py::test_automatic_pre1956_start_obeys_fixed_end_and_continuity[bound1-continuity]'])\nassert Path(i.__file__).read_text() == original\nraise SystemExit(result)\nPY" + }, + { + "name": "round5_lose_actual_fra_end_bound", + "before": "month, _fra_date(person).replace(day=1) - timedelta(days=1)", + "after": "month, _fra_date(person).replace(day=1) - timedelta(days=0)", + "target_function": "_current_period_start_horizon", + "failed_tests": [ + "tests/test_track_b_insured_status_fix_round_5_possibility.py::test_automatic_pre1956_start_must_precede_fra_month[7-False]" + ], + "command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/round5-epuf POPULACE_DYNAMICS_PSID_DIR=/nonexistent/round5-psid /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/mutate_round5_possibility.py lose_actual_fra_end_bound", + "summary": "1 failed, 1 passed in 5.80s; the alternate freeze cannot first begin at the FRA month boundary after its statutory end.", + "isolated": true, + "restored": true, + "restoration": "Only inspect.getsource(_current_period_start_horizon) was mutated and executed in the canonical module dictionary in an isolated process. The harness never wrote implementation files; process exit discarded the mutant.", + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round5 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round5 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport inspect\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\nsource = inspect.getsource(i._current_period_start_horizon)\nbefore = 'month, _fra_date(person).replace(day=1) - timedelta(days=1)'\nafter = 'month, _fra_date(person).replace(day=1) - timedelta(days=0)'\nassert source.count(before) == 1\nexec(compile(source.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', '--tb=short', 'tests/test_track_b_insured_status_fix_round_5_possibility.py::test_automatic_pre1956_start_must_precede_fra_month[7-False]'])\nassert Path(i.__file__).read_text() == original\nraise SystemExit(result)\nPY" + }, + { + "id": "r5-sspa-reject-wrong-number-exemption", + "location": "src/populace_dynamics/track_b/insured_status.py::_sspa211_applicability", + "mutation": "if (legacy is False and person.sspa211_applies) or ( -> if (legacy is not None and legacy != person.sspa211_applies) or ( (in-memory function mutation only; birth condition retained)", + "command": "OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/round5-insured POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/round5-insured PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nimport inspect\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\nsource = inspect.getsource(i._sspa211_applicability)\nbefore = 'if (legacy is False and person.sspa211_applies) or ('\nafter = 'if (legacy is not None and legacy != person.sspa211_applies) or ('\nassert source.count(before) == 1\nexec(source.replace(before, after), i.__dict__)\nraise SystemExit(pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', 'tests/test_track_b_insured_status_fix_round_5_sspa.py::test_reviewed_post2003_assignment_accepts_observed_wrong_number_exemption']))\nPY", + "failed_tests": [ + "tests/test_track_b_insured_status_fix_round_5_sspa.py::test_reviewed_post2003_assignment_accepts_observed_wrong_number_exemption" + ], + "result": "1 failed in 3.25s", + "restored": true, + "before": " if (legacy is False and person.sspa211_applies) or (\n person.alien_worker\n and person.birth_date >= date(2004, 1, 1)\n and not person.sspa211_applies\n ):", + "after": " if (legacy is not None and legacy != person.sspa211_applies) or (\n person.alien_worker\n and person.birth_date >= date(2004, 1, 1)\n and not person.sspa211_applies\n ):", + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round5 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round5 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport inspect\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\nsource = original\nbefore = ' if (legacy is False and person.sspa211_applies) or (\\n person.alien_worker\\n and person.birth_date >= date(2004, 1, 1)\\n and not person.sspa211_applies\\n ):'\nafter = ' if (legacy is not None and legacy != person.sspa211_applies) or (\\n person.alien_worker\\n and person.birth_date >= date(2004, 1, 1)\\n and not person.sspa211_applies\\n ):'\nassert source.count(before) == 1\nexec(compile(source.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', '--tb=short', 'tests/test_track_b_insured_status_fix_round_5_sspa.py::test_reviewed_post2003_assignment_accepts_observed_wrong_number_exemption'])\nassert Path(i.__file__).read_text() == original\nraise SystemExit(result)\nPY" + }, + { + "id": "r5-sspa-accept-pre2004-applicability", + "location": "src/populace_dynamics/track_b/insured_status.py::_sspa211_applicability", + "mutation": "if (legacy is False and person.sspa211_applies) or ( -> if False or ( (in-memory function mutation only; birth condition retained)", + "command": "OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/round5-insured POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/round5-insured PYTHONPATH=$PWD/src:$PWD /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nimport inspect\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\nsource = inspect.getsource(i._sspa211_applicability)\nbefore = 'if (legacy is False and person.sspa211_applies) or ('\nafter = 'if False or ('\nassert source.count(before) == 1\nexec(source.replace(before, after), i.__dict__)\nraise SystemExit(pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', 'tests/test_track_b_insured_status_fix_round_5_sspa.py', '-k', 'test_pre2004_assignment_cannot_declare_section211_applicable']))\nPY", + "failed_tests": [ + "tests/test_track_b_insured_status_fix_round_5_sspa.py::test_pre2004_assignment_cannot_declare_section211_applicable[condition0]", + "tests/test_track_b_insured_status_fix_round_5_sspa.py::test_pre2004_assignment_cannot_declare_section211_applicable[condition1]" + ], + "result": "2 failed, 23 deselected in 4.37s", + "restored": true, + "before": " if (legacy is False and person.sspa211_applies) or (\n person.alien_worker\n and person.birth_date >= date(2004, 1, 1)\n and not person.sspa211_applies\n ):", + "after": " if False or (\n person.alien_worker\n and person.birth_date >= date(2004, 1, 1)\n and not person.sspa211_applies\n ):", + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round5 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round5 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport inspect\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\nsource = original\nbefore = ' if (legacy is False and person.sspa211_applies) or (\\n person.alien_worker\\n and person.birth_date >= date(2004, 1, 1)\\n and not person.sspa211_applies\\n ):'\nafter = ' if False or (\\n person.alien_worker\\n and person.birth_date >= date(2004, 1, 1)\\n and not person.sspa211_applies\\n ):'\nassert source.count(before) == 1\nexec(compile(source.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', '--tb=short', 'tests/test_track_b_insured_status_fix_round_5_sspa.py::test_pre2004_assignment_cannot_declare_section211_applicable[condition0]', 'tests/test_track_b_insured_status_fix_round_5_sspa.py::test_pre2004_assignment_cannot_declare_section211_applicable[condition1]'])\nassert Path(i.__file__).read_text() == original\nraise SystemExit(result)\nPY" + }, + { + "id": "r5-sspa-accept-impossible-prebirth-exemption", + "location": "src/populace_dynamics/track_b/insured_status.py::_sspa211_applicability", + "mutation": "and person.birth_date >= date(2004, 1, 1) -> and False (in-memory function mutation only)", + "command": "Full reproducible in-memory pytest command is recorded in scratch/review/round5-sspa.md", + "failed_tests": [ + "tests/test_track_b_insured_status_fix_round_5_sspa.py::test_post2003_birth_cannot_declare_wrong_number_exemption[conditions0-assigned-birth1]" + ], + "result": "1 failed in 6.54s", + "restored": true, + "before": "and person.birth_date >= date(2004, 1, 1)", + "after": "and False", + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round5 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round5 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport inspect\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\nsource = original\nbefore = 'and person.birth_date >= date(2004, 1, 1)'\nafter = 'and False'\nassert source.count(before) == 1\nexec(compile(source.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', '--tb=short', 'tests/test_track_b_insured_status_fix_round_5_sspa.py::test_post2003_birth_cannot_declare_wrong_number_exemption[conditions0-assigned-birth1]'])\nassert Path(i.__file__).read_text() == original\nraise SystemExit(result)\nPY" + }, + { + "name": "continuity_does_not_filter_earlier_endings", + "before": "endings = [end for end in endings if end >= through]", + "after": "endings = [end for end in endings]", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python /Users/maxghenis/.subfleet/worktrees/20261031-100240-trackb-fix-insured-5/scratch/review/round5_continuity_mutation.py 0", + "pytest_arguments": [ + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "-q", + "--tb=short", + "tests/test_track_b_insured_status_fix_round_5_continuity.py::test_later_continuity_makes_query_quarter_interior" + ], + "returncode": 1, + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/trackb-round5", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/trackb-round5", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261031-100240-trackb-fix-insured-5/src:/Users/maxghenis/.subfleet/worktrees/20261031-100240-trackb-fix-insured-5" + }, + "restored": true, + "method": "Isolated in-memory implementation mutation; source unchanged.", + "failed_tests": [ + "tests/test_track_b_insured_status_fix_round_5_continuity.py::test_later_continuity_makes_query_quarter_interior[through0]", + "tests/test_track_b_insured_status_fix_round_5_continuity.py::test_later_continuity_makes_query_quarter_interior[through1]" + ], + "summary": "2 failed in 7.37s", + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round5 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round5 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport inspect\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\nsource = original\nbefore = 'endings = [end for end in endings if end >= through]'\nafter = 'endings = [end for end in endings]'\nassert source.count(before) == 1\nexec(compile(source.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', '--tb=short', 'tests/test_track_b_insured_status_fix_round_5_continuity.py::test_later_continuity_makes_query_quarter_interior[through0]', 'tests/test_track_b_insured_status_fix_round_5_continuity.py::test_later_continuity_makes_query_quarter_interior[through1]'])\nassert Path(i.__file__).read_text() == original\nraise SystemExit(result)\nPY" + }, + { + "name": "continuity_excludes_equal_ending", + "before": "endings = [end for end in endings if end >= through]", + "after": "endings = [end for end in endings if end > through]", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python /Users/maxghenis/.subfleet/worktrees/20261031-100240-trackb-fix-insured-5/scratch/review/round5_continuity_mutation.py 1", + "pytest_arguments": [ + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "-q", + "--tb=short", + "tests/test_track_b_insured_status_fix_round_5_continuity.py::test_query_quarter_continuity_retains_ending_ambiguity" + ], + "returncode": 1, + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/trackb-round5", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/trackb-round5", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261031-100240-trackb-fix-insured-5/src:/Users/maxghenis/.subfleet/worktrees/20261031-100240-trackb-fix-insured-5" + }, + "restored": true, + "method": "Isolated in-memory implementation mutation; source unchanged.", + "failed_tests": [ + "tests/test_track_b_insured_status_fix_round_5_continuity.py::test_query_quarter_continuity_retains_ending_ambiguity[through1]" + ], + "summary": "1 failed, 1 passed in 4.87s", + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round5 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round5 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport inspect\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\nsource = original\nbefore = 'endings = [end for end in endings if end >= through]'\nafter = 'endings = [end for end in endings if end > through]'\nassert source.count(before) == 1\nexec(compile(source.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', '--tb=short', 'tests/test_track_b_insured_status_fix_round_5_continuity.py::test_query_quarter_continuity_retains_ending_ambiguity[through1]'])\nassert Path(i.__file__).read_text() == original\nraise SystemExit(result)\nPY" + }, + { + "name": "continuity_does_not_require_establishment", + "before": "if not self.current_disability_period_established:\n raise InvalidFamilyInput(\n \"Period continuity requires established period\"", + "after": "if False:\n raise InvalidFamilyInput(\n \"Period continuity requires established period\"", + "command": "/Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python /Users/maxghenis/.subfleet/worktrees/20261031-100240-trackb-fix-insured-5/scratch/review/round5_continuity_mutation.py 2", + "pytest_arguments": [ + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "-q", + "--tb=short", + "tests/test_track_b_insured_status_fix_round_5_continuity.py::test_continuity_requires_a_possible_established_period" + ], + "returncode": 1, + "environment": { + "OMP_NUM_THREADS": "1", + "POLARS_MAX_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/trackb-round5", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/trackb-round5", + "PYTHONPATH": "/Users/maxghenis/.subfleet/worktrees/20261031-100240-trackb-fix-insured-5/src:/Users/maxghenis/.subfleet/worktrees/20261031-100240-trackb-fix-insured-5" + }, + "restored": true, + "method": "Isolated in-memory implementation mutation; source unchanged.", + "failed_tests": [ + "tests/test_track_b_insured_status_fix_round_5_continuity.py::test_continuity_requires_a_possible_established_period[facts2-through2]" + ], + "summary": "1 failed, 4 passed in 5.98s", + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round5 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round5 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport inspect\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\nsource = original\nbefore = 'if not self.current_disability_period_established:\\n raise InvalidFamilyInput(\\n \"Period continuity requires established period\"'\nafter = 'if False:\\n raise InvalidFamilyInput(\\n \"Period continuity requires established period\"'\nassert source.count(before) == 1\nexec(compile(source.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', '--tb=short', 'tests/test_track_b_insured_status_fix_round_5_continuity.py::test_continuity_requires_a_possible_established_period[facts2-through2]'])\nassert Path(i.__file__).read_text() == original\nraise SystemExit(result)\nPY" + } + ], + "round_5_note": "Ordinary fixed-date and same-filling validity, source-permitted SSPA exemptions and retained birth/assignment contradictions, continuity candidate intersection and validation, and automatic historical/FRA chronology. Every deliberate mutation was caught and discarded or reverted; no existing test assertion was weakened.", + "round_5_final_source_sha256": "04964886c402b0ff44dd958fa0b82b6055730f463fdf660a6e346999e13fd493" } diff --git a/src/populace_dynamics/track_b/insured_status.py b/src/populace_dynamics/track_b/insured_status.py index 079d614dc..0bb17757d 100644 --- a/src/populace_dynamics/track_b/insured_status.py +++ b/src/populace_dynamics/track_b/insured_status.py @@ -10,6 +10,8 @@ period ends no later than the month before full retirement age; an unknown ending includes every candidate end quarter from insured start through query/cap and permitted continuation. The cap never establishes the end. +Dated continuity restricts possible endings without establishing an end; +a date beyond the query quarter makes that quarter interior to the period. Disability tests scan onset and later quarters; period establishment and section 214(c) applicability carry explicit provenance. A declaration is rejected only @@ -176,8 +178,11 @@ def _fact_provenance(provenance, convention_id, label): def _sspa211_applicability(person): - # RS00301.102 B.1/B.3: pre2004 assignments are exempt; an alien - # without a true-identity SSN is subject to the additional requirement. + # RS00301.102 B.1/B.3: pre2004 assignments are exempt. Later or absent + # true-identity assignments ordinarily trigger Section 211, but B.3.b's + # wrong-number SS-5 exception allows an adjudicated exemption when the + # worker could legitimately have been assigned an SSN before 2004. A + # worker born in 2004 or later cannot meet that exception's date limit. legacy = None if person.alien_worker: if person.ssn_never_assigned: @@ -185,7 +190,11 @@ def _sspa211_applicability(person): elif person.ssn_assignment_date is not None: legacy = person.ssn_assignment_date >= date(2004, 1, 1) if person.sspa211_applies is not None: - if legacy is not None and legacy != person.sspa211_applies: + if (legacy is False and person.sspa211_applies) or ( + person.alien_worker + and person.birth_date >= date(2004, 1, 1) + and not person.sspa211_applies + ): raise InvalidFamilyInput("Conflicting SSPA211 applicability facts") return person.sspa211_applies return legacy @@ -285,6 +294,13 @@ class Person: EarningsProvenance.UNKNOWN ) current_disability_period_end_convention_id: str | None = None + current_disability_period_continues_through: date | None = None + current_disability_period_continues_through_provenance: ( + EarningsProvenance + ) = EarningsProvenance.UNKNOWN + current_disability_period_continues_through_convention_id: str | None = ( + None + ) def __post_init__(self): _fact_provenance( @@ -374,6 +390,33 @@ def __post_init__(self): "Established period begins after its statutory FRA end" ) fra_end = fra.replace(day=1) - timedelta(days=1) + _fact_provenance( + self.current_disability_period_continues_through_provenance, + self.current_disability_period_continues_through_convention_id, + "current disability period continuity", + ) + through = self.current_disability_period_continues_through + if ( + self.current_disability_period_continues_through_provenance + is EarningsProvenance.UNKNOWN + ) != (through is None): + raise InvalidFamilyInput( + "Current period continuity must match provenance" + ) + if through is not None: + if not self.current_disability_period_established: + raise InvalidFamilyInput( + "Period continuity requires established period" + ) + if through < self.disability_onset or through > fra_end: + raise InvalidFamilyInput( + "Period continuity outside onset and statutory FRA end" + ) + if ( + self.current_disability_period_end is not None + and through > self.current_disability_period_end + ) or (self.death_date is not None and through > self.death_date): + raise InvalidFamilyInput("Period continuity follows its end") periods = sorted( ( replace(p, end=min(p.end, fra_end)) if p.start < fra else p @@ -756,6 +799,11 @@ def _pre1956_alternate_possible(person, credits, month, exit_month): 1956, 1, 1 ): return False + if person.current_disability_period_established: + # RS00301.480 B.1: a freeze cannot begin before 1952-07-01. + # An independent alternate route still must start before the + # declared ending or known continuity observation. + month = _current_period_start_horizon(person, month) first = max(_qid(person.disability_onset), 1952 * 4 + 2) last = min(_qid(month), 1955 * 4 + 3) for quarter in range(first, last + 1): @@ -850,7 +898,7 @@ def _boundary_variants(rows, periods): if prod(map(len, options)) > 4096: _refuse( InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, - "More than4096 boundary assignments", + "More than 4096 boundary assignments", ) for choices in product(*options): yield dict(zip(years, choices, strict=True)) @@ -1057,6 +1105,11 @@ def _unknown_prior_history_is_empty(person, credits, month, exit_month): current_disability_period_end=None, current_disability_period_end_provenance=EarningsProvenance.UNKNOWN, current_disability_period_end_convention_id=None, + current_disability_period_continues_through=None, + current_disability_period_continues_through_provenance=( + EarningsProvenance.UNKNOWN + ), + current_disability_period_continues_through_convention_id=None, ) if _pre1956_alternate_possible( possible_prior, credits, start, exit_month @@ -1208,6 +1261,11 @@ def _with_current_period(person, credits, month, exit_month): end = min(end, person.death_date) if end < start: raise InvalidFamilyInput("Current period ends before insured start") + if ( + person.current_disability_period_continues_through is not None + and person.current_disability_period_continues_through < start + ): + raise InvalidFamilyInput("Period continuity precedes insured start") period = DisabilityPeriod(start, end) return ( replace( @@ -1227,6 +1285,8 @@ def _current_period_completions(person, completed, start, month): 416(i)(2)(D) and 404.321(c) give alternative administrative endings. FRA/death cap the range; neither establishes its actual ending. End days within one quarter have identical insurance semantics. + A continuity observation removes earlier endings; it never supplies + an ending, including when observed later than the query. """ if ( start is None @@ -1242,6 +1302,9 @@ def _current_period_completions(person, completed, start, month): ] if _qid(cap) > _qid(month): endings.append(cap) + through = person.current_disability_period_continues_through + if through is not None: + endings = [end for end in endings if end >= through] return tuple( replace( completed, @@ -1252,6 +1315,19 @@ def _current_period_completions(person, completed, start, month): ) +def _current_period_start_horizon(person, month): + """Latest possible insured start under immutable period facts.""" + horizon = min(month, _fra_date(person).replace(day=1) - timedelta(days=1)) + for fixed_bound in ( + person.current_disability_period_end, + person.current_disability_period_continues_through, + person.death_date, + ): + if fixed_bound is not None: + horizon = min(horizon, fixed_bound.replace(day=1)) + return horizon + + def _specialist_establishment_possible( person, years, credits, month, exit_month ): @@ -1280,10 +1356,13 @@ def _could_establish_current_period( ): """Reject only a declaration impossible under every possible route. - This is deliberately one-way: yes preserves a candidate or a named - refusal; it never establishes a period. Calendar/schema contradictions - have already been rejected. Ordinary premises cannot exclude a - specialist route or a short DIB-entitled prior period. + A fixed ending or continuity observation bounds the insured start. + Upper credits decide ordinary insurance by that bound, but a derived + prior-quarter overlap must be cleared by that same concrete filling. + Calendar/schema contradictions have already been rejected. Ordinary + premises cannot exclude a specialist route or a short DIB-entitled + prior period. Unresolved prior histories and more than 4096 overlap + fillings remain explicitly outside the exact ordinary predicate. """ if not person.current_disability_period_established: return True @@ -1293,6 +1372,10 @@ def _could_establish_current_period( return True if maximum_qcs < 6: return False + horizon = _current_period_start_horizon(person, month) + rows, _ = _world(person, credits, _qid(horizon), exit_month, False) + if sum(len(_assign_qcs(*row)) for row in rows.values()) < 6: + return False if ( person.prior_disability_periods_provenance is EarningsProvenance.UNKNOWN @@ -1307,27 +1390,73 @@ def _could_establish_current_period( prior_disability_periods_convention_id=None, ) try: - _with_current_period(plain, credits, month, exit_month) + _with_current_period(plain, credits, horizon, exit_month) except InvalidFamilyInput: - # More credits can move the first insured start across a declared - # end or a represented prior-period boundary. Failure to construct - # that upper-credit period is not proof about every completion. - # Retain any UNKNOWN-credit declaration with an ordinary insured - # candidate; a public completion failure then receives a refusal. - return ( - any( - row.provenance is EarningsProvenance.UNKNOWN - for row in years.values() + pass + else: + return True + # Ordinary insurance by a fixed date is monotone in credited quarters. + # An upper-credit failure here therefore disproves every ordinary + # filling, even if the same record first qualifies after the ending. + if not _decision_witness( + plain, credits, horizon, exit_month, InsuredTest.DISABILITY + )[0][0]: + return False + unknown = tuple( + year + for year, row in sorted(years.items()) + if row.provenance is EarningsProvenance.UNKNOWN + and year <= horizon.year + ) + if not unknown: + return False + lower = dict(credits) + lower.update({year: ((), 0) for year in unknown}) + try: + _with_current_period(plain, lower, horizon, exit_month) + except InvalidFamilyInput: + pass + else: + return True + # A later witness alone does not suffice: the first insured quarter + # must both avoid the represented prior period and precede the fixed + # bound. Enumerate complete fillings only in this nonmonotone corner. + options = [] + for year in unknown: + allowed = rows.get(year, ((), 0, ()))[2] + if year < 1978: + options.append( + tuple( + ( + tuple( + q + for q, flag in zip(allowed, flags, strict=True) + if flag + ), + 0, + ) + for flags in product((False, True), repeat=len(allowed)) + ) ) - and _decision_witness( - plain, - credits, - min(month, _fra_date(plain).replace(day=1)), - exit_month, - InsuredTest.DISABILITY, - )[0][0] + else: + options.append( + tuple(((), count) for count in range(len(allowed) + 1)) + ) + if prod(map(len, options)) > 4096: + _refuse( + InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, + "More than 4096 current-period overlap fillings; " + "ordinary establishment validity is unresolved", ) - return True + for choices in product(*options): + filling = dict(credits) + filling.update(zip(unknown, choices, strict=True)) + try: + _with_current_period(plain, filling, horizon, exit_month) + except InvalidFamilyInput: + continue + return True + return False def _dli_cap(person, month, exit_month): @@ -1353,8 +1482,10 @@ def insured_status( Medical onset means continuously disabled through this query and never establishes a period. Declare establishment, prior-period provenance, - and section214(c) applicability; UNKNOWN never silently means none. + and section 214(c) applicability; UNKNOWN never silently means none. Declare an administrative ending with its provenance when known. An + observed continues-through date instead excludes earlier endings and + may be later than the query; it does not declare an endpoint. An ongoing period is bounded by possible endings, with a named refusal if the ending changes a requested status, and is always capped before FRA. Each disability window ends at its tested quarter, from onset through @@ -1635,7 +1766,7 @@ def insured_status( ) and _qid(hi_date) == _qid(month) if applicability is None: # A guaranteed historical fully insured witness also needs - # resolved section214(c) facts. Keep the QC-only upper date; + # resolved section 214(c) facts. Keep the QC-only upper date; # false current status cannot prove a positive DLI lower date. lo_date = None dli = _computed(DLIRange, lo_date, hi_date, lo_censored or hi_censored) @@ -1697,6 +1828,10 @@ def insured_status( "current_disability_period_end", person.current_disability_period_end_convention_id, ), + ( + "current_disability_period_continues_through", + person.current_disability_period_continues_through_convention_id, + ), ("sspa211_applicability", person.sspa211_convention_id), ) if identifier is not None diff --git a/tests/README-tiers.md b/tests/README-tiers.md index f63751862..db823dc6c 100644 --- a/tests/README-tiers.md +++ b/tests/README-tiers.md @@ -39,9 +39,9 @@ pytest --collect-only -q -m oracle_policyengine | tail -1 | Tier | Tests at HEAD | |---|---:| -| `unit` | 20,493 | +| `unit` | 20,585 | | `artifact` | 4,271 | | `integration_psid` | 1,471 | | `reproduction_legacy` | 520 | | `oracle_policyengine` | 308 | -| **Total** | **27,063** | +| **Total** | **27,155** | diff --git a/tests/test_track_b_insured_status_fix_round_5_continuity.py b/tests/test_track_b_insured_status_fix_round_5_continuity.py new file mode 100644 index 000000000..bd9e8f0a0 --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_5_continuity.py @@ -0,0 +1,223 @@ +"""Statutory conformance: observed continuity restricts possible endings. + +Invented declarations only; no population, behavioral, or forecast claim. +""" + +import calendar +from dataclasses import fields, replace +from datetime import date + +import pytest +from hypothesis import given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as i +from populace_dynamics.track_b.gross_benefits import InvalidFamilyInput +from tests.test_track_b_insured_status import history +from tests.test_track_b_insured_status_fix_round_4_endings import ( + _declared, + _person, +) + +OBSERVED = i.EarningsProvenance.OBSERVED +UNKNOWN = i.EarningsProvenance.UNKNOWN +CONVENTION = i.EarningsProvenance.CONVENTION_FILLED + + +def _running(person, through, **facts): + return replace( + person, + current_disability_period_continues_through=through, + current_disability_period_continues_through_provenance=OBSERVED, + **facts, + ) + + +@pytest.mark.parametrize("through", [date(2026, 3, 1), date(2026, 3, 31)]) +def test_query_quarter_continuity_retains_ending_ambiguity(through): + person = _running(_person(), through) + month = date(2026, 3, 1) + years = history(person, month, {2017: 1, 2020: 4, 2021: 1, 2026: 1}) + with pytest.raises(i.InsuredConfigurationUnsupported) as exc: + i.insured_status(person, years, month, test=i.InsuredTest.CURRENTLY) + assert exc.value.reason is i.InsuredUnsupportedReason.CURRENT_PERIOD_END + end_of_query = i.insured_status( + _declared(person, date(2026, 3, 31)), + years, + month, + test=i.InsuredTest.CURRENTLY, + ).currently + later = i.insured_status( + _declared(person, date(2026, 6, 30)), + years, + month, + test=i.InsuredTest.CURRENTLY, + ).currently + assert end_of_query.insured and end_of_query.qc_count_lower == 6 + assert not later.insured and later.qc_count_lower == 5 + + +@pytest.mark.parametrize("through", [date(2026, 4, 1), date(2027, 1, 1)]) +def test_later_continuity_makes_query_quarter_interior(through): + person = _running(_person(), through) + month = date(2026, 3, 1) + result = i.insured_status( + person, + history(person, month, {2017: 1, 2020: 4, 2021: 1, 2026: 1}), + month, + test=i.InsuredTest.CURRENTLY, + ) + assert not result.currently.insured + assert ( + result.currently.qc_count_lower == result.currently.qc_count_upper == 5 + ) + assert "current_disability_period_end" in result.unknown_facts + + +def test_age62_continuity_settles_full_insurance_without_an_end(): + person = _running(_person(), date(2062, 2, 1)) + month = date(2062, 2, 1) + result = i.insured_status( + person, + history(person, month, {2017: 1, 2020: 4, 2021: 1}), + month, + test=i.InsuredTest.FULLY, + ) + assert result.fully.insured + assert result.fully.required == result.fully.upper_required == 6 + assert result.fully.qc_count_lower == result.fully.qc_count_upper == 6 + assert person.current_disability_period_end is None + + +@pytest.mark.parametrize( + "facts", + [ + {"current_disability_period_continues_through": date(2026, 1, 1)}, + {"current_disability_period_continues_through_provenance": OBSERVED}, + { + "current_disability_period_continues_through": date(2026, 1, 1), + "current_disability_period_continues_through_provenance": CONVENTION, + }, + { + "current_disability_period_continues_through_convention_id": "unused" + }, + ], +) +def test_continuity_fact_must_match_its_provenance(facts): + with pytest.raises(InvalidFamilyInput): + replace(_person(), **facts) + + +@pytest.mark.parametrize( + "facts,through", + [ + ({}, date(2022, 1, 14)), + ({}, date(2067, 2, 1)), + ( + { + "current_disability_period_established": False, + }, + date(2026, 1, 1), + ), + ( + { + "current_disability_period_end": date(2025, 12, 31), + "current_disability_period_end_provenance": OBSERVED, + }, + date(2026, 1, 1), + ), + ({"death_date": date(2025, 12, 31)}, date(2026, 1, 1)), + ], +) +def test_continuity_requires_a_possible_established_period(facts, through): + with pytest.raises(InvalidFamilyInput): + _running(replace(_person(), **facts), through) + + +def test_continuity_cannot_precede_the_first_insured_start(): + person = _running(_person(), date(2022, 1, 31)) + month = date(2022, 10, 1) + with pytest.raises(InvalidFamilyInput): + i.insured_status( + person, + history(person, month, {2021: 4, 2022: 4}), + month, + test=i.InsuredTest.FULLY, + ) + + +def test_continuity_convention_is_reported_and_old_positional_fields_stay(): + person = replace( + _person(), + current_disability_period_continues_through=date(2026, 4, 1), + current_disability_period_continues_through_provenance=CONVENTION, + current_disability_period_continues_through_convention_id="running-v1", + ) + names = [field.name for field in fields(i.Person)] + assert names[-4] == "current_disability_period_end_convention_id" + assert names[-3:] == [ + "current_disability_period_continues_through", + "current_disability_period_continues_through_provenance", + "current_disability_period_continues_through_convention_id", + ] + result = i.insured_status( + person, + history(person, date(2026, 3, 1), {2020: 4, 2021: 2}), + date(2026, 3, 1), + test=i.InsuredTest.FULLY, + ) + assert ( + result.convention_facts["current_disability_period_continues_through"] + == "running-v1" + ) + + +@settings(max_examples=20, deadline=None) +@given( + through_month=st.integers(1, 12), + recent=st.integers(0, 4), + kind=st.sampled_from([i.InsuredTest.FULLY, i.InsuredTest.CURRENTLY]), +) +def test_continuity_only_narrows_candidates_and_all_concrete_ends_agree( + through_month, recent, kind +): + person = _person() + through = date(2026, through_month, 1) + running = _running(person, through) + month = date(2026, 3, 1) + years = history(person, month, {2017: 1, 2020: 4, 2021: 1, 2026: recent}) + credits = { + year: i._credits(year, row, False) for year, row in years.items() + } + completed, start = i._with_current_period(person, credits, month, None) + candidates = i._current_period_completions(person, completed, start, month) + narrowed = i._current_period_completions(running, completed, start, month) + all_ends = {p.prior_disability_periods[-1].end for p in candidates} + ends = {p.prior_disability_periods[-1].end for p in narrowed} + assert ends == {end for end in all_ends if end >= through} + assert ends <= all_ends + try: + result = i.insured_status(running, years, month, test=kind) + except i.InsuredConfigurationUnsupported as exc: + assert exc.reason is i.InsuredUnsupportedReason.CURRENT_PERIOD_END + return + decision = getattr(result, kind.value) + # Quarter endpoints are independent concrete administrative declarations. + for year in (2026, 2027): + for end_month in (3, 6, 9, 12): + ending = date( + year, end_month, calendar.monthrange(year, end_month)[1] + ) + if ending < through: + continue + concrete = i.insured_status( + _declared(running, ending), years, month, test=kind + ) + concrete_decision = getattr(concrete, kind.value) + assert decision.insured == concrete_decision.insured + assert ( + decision.qc_count_lower + <= concrete_decision.qc_count_lower + <= concrete_decision.qc_count_upper + <= decision.qc_count_upper + ) diff --git a/tests/test_track_b_insured_status_fix_round_5_possibility.py b/tests/test_track_b_insured_status_fix_round_5_possibility.py new file mode 100644 index 000000000..d733bb94b --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_5_possibility.py @@ -0,0 +1,372 @@ +"""Statutory conformance: both directions of period possibility. + +Invented declarations only; no population, behavioral, or forecast claim. +""" + +import calendar +from dataclasses import replace +from datetime import date +from fractions import Fraction +from itertools import product + +import pytest +from hypothesis import example, given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as i +from populace_dynamics.track_b.gross_benefits import count_family_outcomes +from tests.test_track_b_insured_status import declared, history +from tests.test_track_b_insured_status_fix_round_4_routes import ( + _pre1956_case, + _prior_overlap_unknown_earnings_case, + _short_period_case, +) + +OBSERVED = i.EarningsProvenance.OBSERVED +UNKNOWN = i.EarningsProvenance.UNKNOWN + + +def _fixed_end_case(*, previous=4, ending_month=1, query_month=4): + ending = date( + 2022, ending_month, calendar.monthrange(2022, ending_month)[1] + ) + person = i.Person( + date(2000, 2, 2), + disability_onset=date(2022, 1, 15), + prior_disability_periods_provenance=OBSERVED, + current_disability_period_established=True, + current_disability_period_provenance=OBSERVED, + current_disability_period_end=ending, + current_disability_period_end_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + month = date(2022, query_month, 1) + years = history(person, month, {2021: previous}) + years[2022] = i.CoverageYear(UNKNOWN) + return person, years, month + + +def _classification(person, years, month): + rows = [] + try: + rows.append( + i.evaluate_insured_status( + "possibility", + Fraction(3, 2), + lambda: i.insured_status( + person, years, month, test=i.InsuredTest.FULLY + ), + ) + ) + except i.InvalidFamilyInput: + assert not rows + return False + denominator = count_family_outcomes(rows) + assert denominator.rows == 1 + assert denominator.weight == Fraction(3, 2) + return True + + +def test_impossible_fixed_end_raises_from_evaluator_without_a_row(): + person, years, month = _fixed_end_case() + for count in range(5): + concrete = dict(years) + concrete[2022] = declared(count) + assert not _classification(person, concrete, month) + assert not _classification(person, years, month) + + +def test_six_qcs_by_fixed_end_preserve_valid_unknown_declaration(): + person, years, month = _fixed_end_case(ending_month=6, query_month=10) + assert _assert_exact_classification(person, years, month) == [ + False, + False, + True, + True, + True, + ] + + +@pytest.mark.parametrize("previous", [2, 3, 4]) +@pytest.mark.parametrize("ending_month", [1, 2, 3]) +def test_no_unknown_filling_can_start_before_fixed_first_quarter_end( + previous, ending_month +): + person, years, month = _fixed_end_case( + previous=previous, ending_month=ending_month, query_month=10 + ) + assert not any( + _classification(person, {**years, 2022: declared(count)}, month) + for count in range(5) + ) + assert not _classification(person, years, month) + + +def _concrete_histories(years, month): + unknown = [ + year for year, row in years.items() if row.provenance is UNKNOWN + ] + options = [] + for year in unknown: + if year < 1978: + allowed = min(4, i._qid(month) - year * 4 + 1) + options.append( + [ + i.CoverageYear( + OBSERVED, + qc_quarters=flags + (False,) * (4 - allowed), + ) + for flags in product((False, True), repeat=allowed) + ] + ) + else: + options.append([declared(count) for count in range(5)]) + for filling in product(*options): + yield {**years, **dict(zip(unknown, filling, strict=True))} + + +def _assert_exact_classification(person, years, month): + # Enumerate every filling, rather than stopping at the first witness. + valid = [ + _classification(person, filling, month) + for filling in _concrete_histories(years, month) + ] + assert _classification(person, years, month) == any(valid) + return valid + + +@settings(max_examples=24, deadline=None) +@given( + previous=st.integers(0, 4), + ending_month=st.sampled_from([1, 3, 6, 12]), + second_unknown=st.booleans(), + blind=st.booleans(), +) +def test_unknown_declaration_exactly_matches_all_concrete_qc_fillings( + previous, ending_month, second_unknown, blind +): + """Both classifications match all five or25 annual-count fillings.""" + person, years, month = _fixed_end_case( + previous=previous, ending_month=ending_month, query_month=10 + ) + person = replace(person, statutory_blindness=blind) + if second_unknown: + years[2020] = i.CoverageYear(UNKNOWN) + _assert_exact_classification(person, years, month) + + +@settings(max_examples=6, deadline=None) +@given( + missing_year=st.integers(1968, 1971), + ending=st.sampled_from( + [date(1972, 3, 31), date(1972, 12, 31), date(1973, 1, 31)] + ), + prior_ends_in_onset_quarter=st.booleans(), +) +def test_overlap_declaration_exactly_matches_every_quarter_filling( + missing_year, ending, prior_ends_in_onset_quarter +): + """A single filling must satisfy the fixed end and derived overlap.""" + person, years, month = _prior_overlap_unknown_earnings_case( + missing_year=missing_year + ) + prior = person.prior_disability_periods[0] + if not prior_ends_in_onset_quarter: + prior = replace(prior, end=date(1971, 12, 31)) + person = replace( + person, + prior_disability_periods=(prior,), + current_disability_period_end=ending, + current_disability_period_end_provenance=OBSERVED, + ) + assert len(_assert_exact_classification(person, years, month)) == 16 + + +def test_different_fillings_cannot_separately_satisfy_end_and_overlap(): + person, years, month = _prior_overlap_unknown_earnings_case() + person = replace( + person, + current_disability_period_end=date(1972, 3, 31), + current_disability_period_end_provenance=OBSERVED, + ) + valid = _assert_exact_classification(person, years, month) + assert valid == [False] * 16 + + +def test_later_quarter_filling_can_clear_overlap_before_fixed_end(): + person, years, month = _prior_overlap_unknown_earnings_case() + person = replace( + person, + current_disability_period_end=date(1972, 12, 31), + current_disability_period_end_provenance=OBSERVED, + ) + valid = _assert_exact_classification(person, years, month) + assert valid == [False] + [True] * 7 + [False] * 8 + + +@pytest.mark.parametrize("condition", [None, *i.CoverageCondition]) +def test_exact_classification_keeps_automatic_and_every_flagged_route( + condition, +): + person, years, month = _pre1956_case() + if condition is not None: + person = replace(person, conditions=(condition,)) + years[1953] = i.CoverageYear(UNKNOWN) + # The captured alternate rule supplies a possible establishment for + # every concrete quarter filling; each flagged route stays independent. + assert _assert_exact_classification(person, years, month) == [True] * 16 + + +@pytest.mark.parametrize("condition", list(i.CoverageCondition)) +def test_exact_classification_keeps_each_independent_flagged_route(condition): + if condition is i.CoverageCondition.RAILROAD_CREDITS: + person = i.Person( + date(1930, 2, 2), + disability_onset=date(1952, 7, 15), + prior_disability_periods_provenance=OBSERVED, + current_disability_period_established=True, + current_disability_period_provenance=OBSERVED, + current_disability_period_end=date(1952, 8, 31), + current_disability_period_end_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + conditions=(condition,), + ) + month = date(1968, 2, 1) + years = history(person, month) + # Ordinary wages are known; separately flagged RR compensation + # is unresolved, so these are not final credited-QC declarations. + years[1950] = i.CoverageYear( + OBSERVED, quarterly_wages=(Fraction(0),) * 4 + ) + years[1953] = i.CoverageYear(UNKNOWN) + expected_fillings = 16 + else: + person, years, month = _fixed_end_case() + person = replace(person, conditions=(condition,)) + expected_fillings = 5 + upper = {year: i._credits(year, row, True) for year, row in years.items()} + assert not i._pre1956_alternate_possible(person, upper, month, None) + assert ( + _assert_exact_classification(person, years, month) + == [True] * expected_fillings + ) + + +def test_exact_classification_keeps_short_dib_entitled_prior_filling(): + person, years, month = _short_period_case() + concrete = [] + for periods in ( + (), + *( + (i.DisabilityPeriod(date(2028, 10, 1), ending),) + for ending in ( + date(2028, 10, 31), + date(2028, 11, 30), + date(2028, 12, 31), + ) + ), + ): + filled = replace( + person, + prior_disability_periods_provenance=OBSERVED, + prior_disability_periods=periods, + ) + concrete.append(_classification(filled, years, month)) + assert concrete == [False, True, True, True] + assert _classification(person, years, month) == any(concrete) + + +def test_large_unresolved_overlap_has_explicit_complexity_refusal(): + person, years, month = _prior_overlap_unknown_earnings_case() + person = replace( + person, + current_disability_period_end=date(1972, 12, 31), + current_disability_period_end_provenance=OBSERVED, + ) + for year in range(1965, 1971): + years[year] = i.CoverageYear(UNKNOWN) + row = i.evaluate_insured_status( + "large-overlap", + Fraction(3, 2), + lambda: i.insured_status( + person, years, month, test=i.InsuredTest.FULLY + ), + ) + assert ( + row.unsupported.reason + is i.InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY + ) + assert "overlap fillings" in row.unsupported.detail + assert count_family_outcomes((row,)).rows == 1 + + +@pytest.mark.parametrize("fact", ["end", "continuity"]) +@pytest.mark.parametrize( + "bound", + [ + date(1952, 3, 31), + date(1952, 6, 30), + date(1952, 7, 31), + date(1952, 9, 30), + ], +) +def test_automatic_pre1956_start_obeys_fixed_end_and_continuity(fact, bound): + person, years, month = _pre1956_case() + values = {"disability_onset": date(1952, 1, 15)} + if fact == "end": + values.update( + current_disability_period_end=bound, + current_disability_period_end_provenance=OBSERVED, + ) + else: + values.update( + current_disability_period_continues_through=bound, + current_disability_period_continues_through_provenance=OBSERVED, + ) + person = replace(person, **values) + upper = {year: i._credits(year, row, True) for year, row in years.items()} + assert not i._decision_witness( + person, upper, bound, None, i.InsuredTest.DISABILITY + )[0][0] + possible = bound >= date(1952, 7, 1) + assert _classification(person, years, month) is possible + assert ( + i._pre1956_alternate_possible(person, upper, month, None) is possible + ) + + +@settings(max_examples=12, deadline=None) +@example(month=6, fact="end") +@example(month=6, fact="continuity") +@example(month=7, fact="end") +@example(month=7, fact="continuity") +@given(month=st.integers(1, 12), fact=st.sampled_from(["end", "continuity"])) +def test_automatic_pre1956_start_respects_immutable_bound_property( + month, fact +): + bound = date(1952, month, calendar.monthrange(1952, month)[1]) + test_automatic_pre1956_start_obeys_fixed_end_and_continuity(fact, bound) + + +@pytest.mark.parametrize("birth_month,possible", [(7, False), (8, True)]) +def test_automatic_pre1956_start_must_precede_fra_month(birth_month, possible): + person, years, month = _pre1956_case() + person = replace( + person, + birth_date=date(1887, birth_month, 2), + disability_onset=date(1952, 1, 15), + ) + assert i._fra_date(person) == date(1952, birth_month, 1) + assert _classification(person, years, month) is possible + + +@settings(max_examples=11, deadline=None) +@example(birth_month=7) +@example(birth_month=8) +@given(birth_month=st.integers(2, 12)) +def test_automatic_pre1956_start_respects_fra_cap_property(birth_month): + test_automatic_pre1956_start_must_precede_fra_month( + birth_month, birth_month >= 8 + ) diff --git a/tests/test_track_b_insured_status_fix_round_5_sspa.py b/tests/test_track_b_insured_status_fix_round_5_sspa.py new file mode 100644 index 000000000..8b8872f52 --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_5_sspa.py @@ -0,0 +1,245 @@ +"""Statutory conformance: source-required wrong-number SS-5 exemptions. + +Invented declarations only; no population, behavioral, or forecast claim. +The applicability declaration represents the adjudicated Section 211 fact, +including the captured RS 00301.102 B.3.b wrong-number exception. +""" + +from datetime import date +from fractions import Fraction + +import pytest +from hypothesis import given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as i +from populace_dynamics.track_b.gross_benefits import count_family_outcomes +from tests.test_track_b_insured_status import history +from tests.test_track_b_insured_status_sources import source_text + +OBSERVED = i.EarningsProvenance.OBSERVED +PROPERTY = settings(max_examples=30, deadline=None) + + +def _person(birth=date(1980, 2, 2), **values): + facts = { + "alien_worker": True, + "prior_disability_periods_provenance": OBSERVED, + "current_disability_period_established": False, + "current_disability_period_provenance": OBSERVED, + "sspa211_applies": False, + "sspa211_provenance": OBSERVED, + } + facts.update(values) + return i.Person(birth, **facts) + + +def _evaluate(person, counts=None, *, month=date(2006, 1, 1)): + years = history(person, month, counts or {2004: 4, 2005: 2}) + return i.evaluate_insured_status( + "wrong-number-ss5", + Fraction(3, 2), + lambda: i.insured_status( + person, years, month, test=i.InsuredTest.FULLY + ), + ) + + +def test_reviewed_post2003_assignment_accepts_observed_wrong_number_exemption(): + person = _person(ssn_assignment_date=date(2004, 1, 1)) + row = _evaluate(person) + assert row.supported + assert row.result.fully.insured + assert row.result.fully.required == 6 + assert row.result.fully.qc_count_lower == 6 + assert row.result.fully.qc_count_upper == 6 + count = count_family_outcomes((row,)) + assert count.rows == count.supported_rows == 1 + assert count.weight == Fraction(3, 2) + + +def test_never_assigned_true_identity_ssn_can_have_wrong_number_exemption(): + row = _evaluate(_person(ssn_never_assigned=True)) + assert row.supported + assert row.result.fully.insured + assert row.result.fully.required == 6 + assert row.result.fully.qc_count_lower == 6 + assert row.result.fully.qc_count_upper == 6 + + +@pytest.mark.parametrize( + "condition", [(), (i.CoverageCondition.MILITARY_CREDITS,)] +) +def test_pre2004_assignment_cannot_declare_section211_applicable(condition): + person = _person( + ssn_assignment_date=date(2003, 12, 31), + sspa211_applies=True, + conditions=condition, + ) + with pytest.raises( + i.InvalidFamilyInput, match="Conflicting SSPA211 applicability facts" + ): + _evaluate(person) + + +@pytest.mark.parametrize( + "facts", + [ + {"ssn_assignment_date": date(2004, 1, 1)}, + {"ssn_never_assigned": True}, + ], +) +def test_unadjudicated_date_and_never_assigned_presumptions_still_apply(facts): + row = _evaluate( + _person( + **facts, + sspa211_applies=None, + sspa211_provenance=i.EarningsProvenance.UNKNOWN, + ) + ) + assert not row.supported + assert row.unsupported.reason is i.InsuredUnsupportedReason.ALIEN_WORKER + assert count_family_outcomes((row,)).rows == 1 + + +@PROPERTY +@given( + first=st.integers(0, 4), + second=st.integers(0, 4), + never_assigned=st.booleans(), + provenance=st.sampled_from( + [OBSERVED, i.EarningsProvenance.CONVENTION_FILLED] + ), +) +def test_adjudicated_exemption_preserves_ordinary_count_and_evaluator_row( + first, second, never_assigned, provenance +): + person = _person( + ssn_assignment_date=None if never_assigned else date(2004, 1, 1), + ssn_never_assigned=never_assigned, + sspa211_provenance=provenance, + sspa211_convention_id=( + "invented-wrong-number-exemption" + if provenance is i.EarningsProvenance.CONVENTION_FILLED + else None + ), + ) + row = _evaluate(person, {2004: first, 2005: second}) + decision = row.result.fully + assert decision.insured is (first + second >= 6) + assert decision.required == 6 + assert decision.qc_count_lower == decision.qc_count_upper == first + second + count = count_family_outcomes((row,)) + assert count.rows == count.supported_rows == 1 + assert count.weight == Fraction(3, 2) + + +@PROPERTY +@given( + assignment=st.dates(date(1980, 2, 2), date(2003, 12, 31)), + applies=st.booleans(), +) +def test_pre2004_assignment_accepts_exactly_the_exempt_applicability( + assignment, applies +): + person = _person(ssn_assignment_date=assignment, sspa211_applies=applies) + if applies: + with pytest.raises( + i.InvalidFamilyInput, + match="Conflicting SSPA211 applicability facts", + ): + _evaluate(person) + else: + row = _evaluate(person) + assert row.supported + assert row.result.fully.insured + assert count_family_outcomes((row,)).rows == 1 + + +@pytest.mark.parametrize("birth", [date(2005, 1, 1), date(2004, 1, 1)]) +@pytest.mark.parametrize("assignment_facts", ["assigned", "never", "unknown"]) +@pytest.mark.parametrize( + "conditions", [(), (i.CoverageCondition.MILITARY_CREDITS,)] +) +def test_post2003_birth_cannot_declare_wrong_number_exemption( + birth, assignment_facts, conditions +): + """Executed audit case and exact cutoff: no legitimate prebirth SSN.""" + person = _person( + birth, + ssn_assignment_date=( + birth if assignment_facts == "assigned" else None + ), + ssn_never_assigned=assignment_facts == "never", + conditions=conditions, + ) + with pytest.raises( + i.InvalidFamilyInput, match="Conflicting SSPA211 applicability facts" + ): + _evaluate(person, {2023: 4, 2024: 2}, month=date(2026, 1, 1)) + + +@PROPERTY +@given( + birth=st.dates(date(2003, 1, 1), date(2005, 12, 31)), + assignment_facts=st.sampled_from(["assigned", "never", "unknown"]), + first=st.integers(0, 4), + second=st.integers(0, 4), +) +def test_wrong_number_exemption_requires_possible_pre2004_assignment( + birth, assignment_facts, first, second +): + person = _person( + birth, + ssn_assignment_date=( + max(birth, date(2004, 1, 1)) + if assignment_facts == "assigned" + else None + ), + ssn_never_assigned=assignment_facts == "never", + ) + + def compute(): + return _evaluate( + person, {2023: first, 2024: second}, month=date(2026, 1, 1) + ) + + if birth >= date(2004, 1, 1): + with pytest.raises( + i.InvalidFamilyInput, + match="Conflicting SSPA211 applicability facts", + ): + compute() + else: + row = compute() + assert row.supported + assert row.result.fully.insured is (first + second >= 6) + assert row.result.fully.required == 6 + assert ( + row.result.fully.qc_count_lower + == row.result.fully.qc_count_upper + == first + second + ) + assert count_family_outcomes((row,)).rows == 1 + + +@pytest.mark.parametrize( + "quote", + [ + "If an alien worker could have legitimately been assigned an SSN " + "before 1/1/2004, the worker is exempt from the requirements of " + "section 211 of the SSPA.", + "SSA erroneously issued the alien worker an SSN with another " + "person's SSN instead of assigning the alien worker their own SSN", + "An alien worker whose SSN was assigned before January 1, 2004 is " + "exempt from the requirements of Section 211 of the Social Security " + "Protection Act, even if the SSN was not work authorized.", + "An alien worker who does not have an SSN card for work purposes " + "is nevertheless considered to meet the work SSN requirement of " + "Section 211 of the SSPA if they meet one of the following profiles:", + ], +) +def test_wrong_number_exception_and_retained_contradiction_quote_capture( + quote, +): + assert quote in source_text("poms_rs_00301_102") diff --git a/tests/tier_counts.json b/tests/tier_counts.json index d15067a23..a29190794 100644 --- a/tests/tier_counts.json +++ b/tests/tier_counts.json @@ -1,7 +1,7 @@ { "schema_version": 1, "counts": { - "unit": 20493, + "unit": 20585, "artifact": 4271, "integration_psid": 1471, "reproduction_legacy": 520, From 7a99eb0e17b70d89d6cef7bd0d10051670cc2bf2 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sat, 31 Oct 2026 12:19:58 -0400 Subject: [PATCH 11/46] Apply insured declaration proof order and historical route limits (#562 round 6) Sol's fifth review found that a refusal over an unrelated year ran before the impossibility proof, so an input error became a counted row. The four early conversion refusals now wait for the proof, which uses bounded credits for those rows. A possible declaration keeps its original refusal. RS 00301.480 A's 20/40 precondition now limits the automatic pre-1956 route: a lower-filling witness before October 1960 removes it for every completion, and an upper-only witness leaves it possible. Fixed quarter overlap now raises an input error before any filling search. Round 5's cost finding stays out of this round; a separate task takes it after the merge. The tier files start from the 20,594 unit tests CI collected at 2ae76db2, which my round-5 sum understated by nine, and add this round's 46. The coordinator's slot recount replaces them. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 150 +++++++- .../track_b_insured_status_mutations.json | 222 +++++++++++- .../track_b/insured_status.py | 183 ++++++++-- tests/README-tiers.md | 4 +- ...k_b_insured_status_fix_round_6_ordering.py | 291 +++++++++++++++ ...ack_b_insured_status_fix_round_6_routes.py | 334 ++++++++++++++++++ tests/tier_counts.json | 2 +- 7 files changed, 1140 insertions(+), 46 deletions(-) create mode 100644 tests/test_track_b_insured_status_fix_round_6_ordering.py create mode 100644 tests/test_track_b_insured_status_fix_round_6_routes.py diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index f8ca3ccf2..fe382485a 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -122,7 +122,19 @@ possibility retains its named refusal. The automatically observable alternate-pre1956 scan independently obeys the same immutable start horizon: an ending or continuity observation before July 1952 cannot be rescued by its first permitted July 1, 1952 start (RS .480 B.1). Explicit -specialist declarations remain separately preserved. On the ordinary route, a valid +specialist declarations remain separately preserved. RS .480 A also makes +that automatic alternate unavailable if even the lower-credit filling has +20/40 in a disabled quarter before October 1960. The test uses the ordinary +disability window, including favorable use or disregard of all prior +periods, from onset through the earlier of the query and 1960Q3, +retaining the existing disability scan's FRA-quarter cap for established +periods (404.321). This exclusion scan precedes the alternate start's +fixed-horizon cap: a later +disabled quarter can exclude the route even if the alternate start itself +would have to precede a supplied administrative end. If some feasible +fillings still lack 20/40, application facts remain absent and the +alternate possibility retains its refusal. +On the ordinary route, a valid filling must supply one insured start that is at or before the declared administrative end and clears every prior-period overlap. A later witness at the query cannot rescue an immutable earlier end. The scan therefore @@ -132,6 +144,9 @@ question. If that representative's derived start overlaps a prior period, the rule checks lower-credit fillings and, when needed, enumerates the bounded concrete fillings for a single valid period. It never combines the end compliance of one filling with the overlap compliance of another. +Before that enumeration, it checks whether any candidate starting quarter +from onset through the fixed horizon clears all supplied prior periods. +If none does, no credit route can supply a nonoverlapping start. Only when all routes and feasible fillings are impossible can the rule raise `InvalidFamilyInput` before any coverage refusal. On the ordinary supported QC surface, fewer than six maximum feasible lifetime QCs proves @@ -325,6 +340,15 @@ with known period ends retain exact counts. An ongoing ending can widen counts even when every earnings year is observed. No narrower selected-witness bound is claimed. +An uncomputable raw-earnings row is treated as unknown only while checking +whether declared establishment is possible. Its minimum and maximum +feasible credits are bounded by the same allowed-quarter calendar. These +temporary fillings do not become a supported earnings result or a returned +count envelope: if the declaration survives, the original conversion +refusal fires with its unchanged reason and note. A refused row beyond an +immutable starting horizon cannot hide a declaration that every filling +proves impossible. + If either bound differs on a requested Boolean status, the call raises the sealed `unknown_earnings_years_decide_status` refusal. If both agree, the answer is decided despite unknown years and records all such years. A caller @@ -421,6 +445,24 @@ Input errors are raised before any of these coverage decisions. The enum is `InsuredUnsupportedReason`; the class is `InsuredConfigurationUnsupported`, a subclass of the shared `FamilyConfigurationUnsupported`. +The refusal order starts with full schema and history validation, including +every raw row. The establishment possibility proof then precedes coverage +refusals. Before that proof, raw conversion can encounter only four +reachable refusals: `qc_amount_year_unsupported`, +`1937_earnings_allocation_unsupported`, +`pre1955_agricultural_allocation_unsupported`, and +`pre1951_self_employment_unsupported`. These are deferred while possibility +is tested with each unresolved row's feasible credit fillings. If the +proof finds a possible filling or reaches an unresolved coverage limit, +the first original conversion refusal in year order is raised unchanged. +Proved impossibility instead raises `InvalidFamilyInput`. With no deferred +reason, the existing specialist, date, applicability, and requested-status +checks follow. The evaluator validates its +key, weight, and callback before invoking the callback; it adds no statutory +refusal of its own. It counts a genuine callback refusal only after the +callback's declaration validation has had this opportunity to reject the +input. An input error propagates and creates no row. + | Trigger | Reason code | | --- | --- | | Unknown-year bounds decide a requested status differently | `unknown_earnings_years_decide_status` | @@ -444,7 +486,7 @@ a subclass of the shared `FamilyConfigurationUnsupported`. | Pre1951 self-employment income | `pre1951_self_employment_unsupported` | | Earnings require an increment after 2027 | `qc_amount_year_unsupported` | | Query before 1968; blind query before 1973; subsequent-special query before May 1983 | `entitlement_before_1968_unsupported`, `blindness_before_1973_unsupported`, `subsequent_special_before_1983_unsupported` | -| More than 4,096 disability-boundary combinations, or unresolved ordinary-establishment overlap requiring more than 4,096 credit fillings | `disability_boundary_assignments_unsupported` | +| More than 4,096 disability-boundary combinations, or unresolved ordinary-establishment overlap requiring more than 4,096 credit fillings after the candidate-quarter exclusion check | `disability_boundary_assignments_unsupported` | The round-3 observable-trigger audit covers every `CoverageCondition`. An explicit condition continues to refuse independently of its ordinary @@ -465,7 +507,7 @@ allocation or adjudicate application facts. | Condition | Observable trigger or absent fact | | --- | --- | | `SIMPLIFIED_PRE1951` | Raw 1937–1950 quarterly wages provide an aggregate divided by $400; post1950 upper QCs and the fully insured prerequisite bound whether it could decide status (213(c); 404.110(d); RS .315). UNKNOWN pre1951 years can supply unbounded raw wages and therefore also trigger the refusal. Direct `qc_quarters` declare credited quarters rather than raw wages. The simplified method does not apply to a disability claim. Filing, retroactivity, and section 227 facts remain unmodeled. | -| `DISABILITY_BEFORE_1956` | Medical onset and QCs reveal a possible RS .480 alternative: at least 20 total QCs and every quarter from 1951Q1 through the quarter before a qualifying 1952Q3–1955Q4 candidate quarter at or after onset, with at least six such quarters. For declared current establishment, that candidate must fit the immutable declared-end/continuity/death/FRA horizon. Refuse automatically when this could change a failed disability predicate. Application conditions remain unmodeled. | +| `DISABILITY_BEFORE_1956` | Medical onset and QCs reveal a possible RS .480 alternative: at least 20 total QCs and every quarter from 1951Q1 through the quarter before a qualifying 1952Q3–1955Q4 candidate quarter at or after onset, with at least six such quarters. For declared current establishment, that candidate must fit the immutable declared-end/continuity/death/FRA horizon. RS .480 A excludes the route when the lower-credit filling has 20/40 in the rule's disabled-quarter scan before October 1960; if only some fillings do, the alternate remains possible. Refuse automatically when this could change a failed disability predicate. Application conditions remain unmodeled. | | `DEEMED_FULLY_INSURED` | Wages and dates do not identify covered nonprofit employment or veteran status; retain the explicit flag (404.111–.112; RS .106/.107/.470). | | `TRANSITIONAL_INSURED` | Cohort dates alone do not identify the necessary historical benefit/application facts; retain the explicit flag (RS .101's transitional-benefit referrals). | | `RAILROAD_CREDITS`, `MILITARY_CREDITS` | Ordinary covered earnings do not identify railroad or military service and additional credits; retain explicit flags (RS .350; RS .120/.470). | @@ -545,10 +587,12 @@ to a statutory sentence that does not state it. | I5. A supplied `special_insured` prior period begins before the age-31 attainment quarter. | B404.130(d)(1): a prior period "began before age 31" and the worker "were only insured under paragraph (c)"; (c)(1) requires age 31 not yet attained. A216(i)(3)(B)(iii) expressly uses "before the quarter" of age 31. The flag declares this particular adjudicated young-worker route, not every possible special credit regime. | | I6. An alien worker's actual pre2004 SSN assignment conflicts with declared SSPA applicability; birth on/after January 1, 2004 conflicts with declared exemption. Both never-assigned and an assigned SSN, or assignment before birth, remain invalid. A worker born before 2004 may pair a post2003 assignment or never-assigned status with an adjudicated exemption. | RS .102 B.1 says an alien assigned an SSN before 2004 "is exempt", including a nonwork SSN. B.3.b says, "If an alien worker could have legitimately been assigned an SSN before 1/1/2004, the worker is exempt from the requirements of section 211 of the SSPA." Its wrong-number SS-5 scenario issued another person's number "instead of assigning the alien worker their own SSN". Thus observed or convention-filled exemption overrides either later-assignment or never-assigned presumptions when legitimate pre2004 assignment was possible. Birth on/after January 1, 2004 rules out that exception independently of the assignment record. B.4.b's worker without an SSN "is nevertheless considered to meet the work SSN requirement" when work-authorized; meeting that requirement alone supplies no exemption. | | I7. Explicit quarterly QCs or positive quarterly wages cannot occur before birth, after the query/coverage-end quarter, or after the death quarter. Every required coverage year is declared exactly once through the earliest query, exit, or death year. | A213(a)(2)(B)(i), (v): "no quarter after the quarter in which an individual dies" and "no quarter shall be counted ... prior to the beginning of such quarter"; B404.146(a)-(b) agree. Birth and supplied-record exit caps, complete years, and no implicit zeros are interface premises. Annual counts are capped rather than dated after exit. Specialist earned-basis or additional-credit declarations remain refusals and do not reinterpret an explicit ordinary covered-quarter declaration. | -| I8. A declared current establishment with no possible insured start is invalid only after the shared possibility check excludes every route and every feasible prior/earnings filling. One ordinary filling must satisfy the start, declared end, continuity, and overlap constraints together. | C320(b)(2) requires insured disability "in the calendar quarter in which you became disabled, or in a later calendar quarter"; C321(a) chooses the first such quarter. B404.130(a) says "four different rules"; RS .480 supplies an additional historical test with "at least 20 quarters of coverage" and every qualifying 1951 quarter. Independent flagged and automatic guards preserve those routes; the automatic pre1956 scan obeys the same immutable starting horizon. The ordinary scan is capped by the declared end and continuity date as well as query/death/FRA. Maximum credits decide whether insurance by that fixed date is possible. A failure caused by a derived prior-quarter overlap instead requires a lower-credit or enumerated filling with a nonoverlapping first start by the same cap. A witness after the declared end never supplies possibility. | +| I8. A declared current establishment with no possible insured start is invalid only after the shared possibility check excludes every route and every feasible prior/earnings filling. One ordinary filling must satisfy the start, declared end, continuity, and overlap constraints together. | C320(b)(2) requires insured disability "in the calendar quarter in which you became disabled, or in a later calendar quarter"; C321(a) chooses the first such quarter. B404.130(a) says "four different rules"; RS .480 supplies an additional historical test with "at least 20 quarters of coverage" and every qualifying 1951 quarter, subject to its own 20/40 exclusion and the existing disability scan's FRA-quarter cap (C321). Independent flagged and automatic guards preserve available routes; the automatic pre1956 scan obeys the same immutable starting horizon. The ordinary scan is capped by the declared end and continuity date as well as query/death/FRA. Maximum credits decide whether insurance by that fixed date is possible. A failure caused by a derived prior-quarter overlap first checks whether any candidate starting quarter clears the supplied periods, then requires a lower-credit or enumerated filling with a nonoverlapping first start by the same cap. A witness after the declared end never supplies possibility. | | I9. Fewer than six maximum feasible ordinary lifetime QCs proves current establishment impossible only when all specialist possibilities have already been excluded. | B404.110(b)(1): "You need at least 6 QCs but not more than 40 QCs"; B404.130(a): "you must be fully insured". B404.110(a) separately names deemed veteran/nonprofit routes, and RS .131/.350 cover other credits. Those alternatives prevent applying the ordinary six-QC input-error proof to a potentially valid specialist declaration. A record composed entirely of direct final QC declarations (`qc_count` or `qc_quarters`) and UNKNOWN years already fixes or bounds all admissible QCs, including RR credits, so the RR flag cannot add quarters beyond that envelope. This is the direct-credit input contract, not a claim that ordinary RSDI credits always exhaust freeze credits: RS .131 expressly allows credits "not creditable for other" purposes. If earnings allocation or that final-credit declaration is unresolved, the RR route remains possible; RS .230 and .350 supply annual and historical RR credit rules. Period exclusions alone cannot add ordinary QCs. | | I10. The supported calendar, mandatory historical sex, and explicit establishment declaration must be supplied: birth years 1870–9900, query years through 9990, sex for births before January 2, 1913, and establishment provenance whenever onset is present. | These are interface-domain requirements. B404.110(b)(2) and .132 apply different historical male/female endpoints; B404.110(c) excludes only a period "we established for you". Missing facts are not inferred. Calendar limits reserve space for date arithmetic and assert no legal incapacity outside the implementation domain; alternative credit routes cannot supply missing declared facts. | | I11. A continues-through observation requires established disability, cannot precede medical onset or the first feasible insured start, cannot exceed the pre-FRA or death boundary, and cannot follow a declared administrative end. | C320(b)(2) and C321(a) require the insured start; A216(i)(2)(D) and C321(c) bound the period's end. A declaration that a period was in force on a date requires that date to lie within one possible period. This is a dated observation, not an asserted ending; a date later than the query is allowed. Provenance and convention identifiers follow the existing fact schema. | +| I12. A raw-credit conversion refusal cannot hide established-period impossibility that every feasible filling of that row preserves. | C320(b)(2), C321(a), and B404.110(b)(1) supply the insured-start and six-QC premises. The #530 input contract puts input errors before coverage refusals. Schema validation remains first; the four conversion refusals are deferred only for this proof, with unresolved rows bounded by feasible ordinary quarters. A surviving filling preserves the original refusal reason and note rather than manufacturing a supported status. | +| I13. If no starting quarter from onset through the immutable horizon clears all supplied prior-period quarters, current establishment is impossible independently of credit fillings, their count, or a specialist route. | C320(b)(2) and C321(a) require an insured beginning within that interval; I4's nonoverlapping-quarter representation applies to that same beginning. A credit route cannot move a candidate outside the fixed interval or remove a supplied prior quarter. This fixed contradiction is checked before specialist possibility and filling enumeration; it does not treat UNKNOWN prior history as supplied empty history. | | ID and UNKNOWN collapse | Captured text and alternative-route defense | | --- | --- | @@ -556,18 +600,19 @@ to a statutory sentence that does not state it. | U2. UNKNOWN current establishment needs no new-period alternative if there is no medical onset or onset is at/after the statutory latest starting month. | A216(i)(2)(A)-(D) and C321 prohibit a period without disability or a nonempty pre-FRA interval. This removes an impossible new-period alternative only; it does not remove UNKNOWN prior history or an existing period's UNKNOWN administrative end. | | U3. With unknown prior/current periods, true ordinary status under favorable all-period disregard decides true. | C320(a): "If benefits ... would be denied or reduced because of a period of disability, the period of disability will not be taken into consideration." B404.130(f) also permits counting all prior quarters if favorable. RS .120 requires all periods used or all disregarded; selective exclusions are not assumed. Specialist credit regimes are refused first. | | U4. With unknown periods, fewer than six maximum feasible QCs decides false only on the ordinary route after specialist possibilities are excluded. | B404.110(b)(1) and B404.130(a) supply the six-QC prerequisite. U3's disregard cannot manufacture credits. Deemed, transitional, foreign, military/railroad, and automatically revealed historical alternatives retain named refusals instead of using this ordinary collapse. | -| U5. UNKNOWN earnings decide a requested Boolean only if all lower/upper ordinary earnings witnesses agree, under the permitted fixed-period/all-period treatments; an uncertain established start refuses only after at least one feasible filling survives. | B404.143 credits one QC for each increment, maximum four; B404.130 and .146 supply assignment/exclusion rules. Adding ordinary QCs cannot invalidate a fixed treatment. A derived start cannot be silently held fixed when the completion changes it. If a lower or upper representative cannot construct the declared period, but another single filling meets its end, continuity, and prior-overlap constraints, the public result is `unknown_earnings_years_decide_status`. If no ordinary filling can qualify by the declared end and all independent routes are impossible, it is an input error and creates no row. Specialist possibilities and administrative-end candidates are considered separately. | +| U5. UNKNOWN earnings decide a requested Boolean only if all lower/upper ordinary earnings witnesses agree, under the permitted fixed-period/all-period treatments; an uncertain established start refuses only after at least one feasible filling survives. | B404.143 credits one QC for each increment, maximum four; B404.130 and .146 supply assignment/exclusion rules. Adding ordinary QCs cannot invalidate a fixed treatment. A derived start cannot be silently held fixed when the completion changes it. If a lower or upper representative cannot construct the declared period, but another single filling meets its end, continuity, and prior-overlap constraints, the public result is `unknown_earnings_years_decide_status`. If no ordinary filling can qualify by the declared end and all independent routes are impossible, it is an input error and creates no row. A deferred raw-conversion row uses temporary unknown fillings only for possibility, then retains its conversion refusal. Specialist possibilities and administrative-end candidates are considered separately. | | U6. UNKNOWN administrative end decides a status only when every end-quarter candidate from start through query/cap, plus permitted continuation, agrees, after applying any continuity lower bound. | A216(i)(2)(D) uses "whichever ... is the earlier"; C321(c)(3) includes "the last month for which you received benefits" after substantial gainful activity. Medical continuity cannot exclude early ends; a dated administrative continuity observation can. FRA/death caps limit the latest candidate and do not turn the unknown into a fact. Both ending and prior-history unknown facts remain disclosed when both are missing; UNKNOWN prior history uses the universal envelopes rather than inventing a derived current period to enumerate. An actual supplied end keeps its declared-date semantics; known ending provenance requires an ending date. | | U7. UNKNOWN SSPA applicability preserves an ordinary QC-only false status, but never a QC-only true status. | RS .102 B.2 says the worker "must meet one of the following additional requirements" and may fail "even if" the QC requirement is met. Applicability can remove ordinary insurance and cannot supply missing QCs. Known applicability retains adjudication refusal; any separate specialist path is refused first. | | U8. With UNKNOWN prior history, a known current period's start is certain onset only if the lower-credit favorable-disregard witness already insures at onset; otherwise the start stays unknown. | A216(i)(2)(C) and C321(a) make insured onset the earliest legal start. C320(a)'s disregard permits that witness, and no route can move this period before medical onset. Other potentially valid histories prevent an impossibility error but do not fabricate a start. | | U9. A continues-through observation removes only candidate administrative ends before its date; it never supplies an ending endpoint or removes UNKNOWN-end disclosure. | C321(c) enumerates actual ending events. Observation of a period still in force supplies a lower bound on those events, not their occurrence. Same-quarter ends remain possible, while a later-quarter observation makes the query quarter interior. | +| U10. An automatic alternate-pre1956 possibility can be removed for every filling only when the lower-credit filling already has ordinary 20/40 in the route's disabled-quarter scan before October 1960. | RS .480 A makes the test available only to a disabled worker who "does not have 20/40 for freeze or DIB in any quarter before 10/60". Ordinary fixed-treatment recent-credit counts are monotone in added credits. The scan uses the ordinary 40-quarter window with favorable all-period use/disregard, from onset through the earlier of query and 1960Q3, retaining the existing FRA-quarter cap for established periods (C321); it does not substitute the young-worker or blindness rule and is not capped by an earlier administrative end. A lower-credit 20/40 witness therefore excludes the alternate for every completion; an upper-only witness cannot do so. Application facts remain absent and are not inferred from this exclusion. The same guard is used for current-establishment and earliest-prior-history possibilities. | | ID and bound | Captured text and alternative-route defense | | --- | --- | -| B1. UNKNOWN annual ordinary QCs range from zero through four, reduced by assignable birth/query/death/exit quarters. Exact annual amounts are monotone in earnings; every calendar year stays in 0–4. | B404.143: "we cannot credit you with more than four QCs for any calendar year"; A213(a)(2)(B)(vi) prohibits duplicate calendar-quarter QCs; B404.146 excludes unbegun/death quarters. Birth/exit are supplied-record premises. Additional-credit regimes retain refusal and cannot escape this bound through an ordinary result. | +| B1. UNKNOWN annual ordinary QCs range from zero through four, reduced by assignable birth/query/death/exit quarters. Deferred raw-conversion rows use their feasible minimum/maximum fillings only for establishment possibility. Exact annual amounts are monotone in earnings; every calendar year stays in 0–4. | B404.143: "we cannot credit you with more than four QCs for any calendar year"; A213(a)(2)(B)(vi) prohibits duplicate calendar-quarter QCs; B404.146 excludes unbegun/death quarters. Birth/exit are supplied-record premises. Additional-credit regimes retain refusal and cannot escape this bound through an ordinary result. Deferred rows still raise their original conversion refusal after a valid possibility survives; no temporary filling is exposed as a computed status. | | B2. Ordinary fully insured requirements lie in 6–40 and exclude only established disability years. Every elapsed-year endpoint uses its relevant candidate year and the historical sex/cohort rule. | B404.110(b)(1), (b)(2), (c), .132; A214(a) says "not counting ... any year any part of which was included in a period of disability". Medical onset without establishment cannot freeze years. Deemed/transitional alternatives are refused before using the ordinary requirement as universal. | | B3. A simplified-pre1951 possibility uses the smallest known freeze requirement, or six for unresolved establishment/history, and maximum post1950 ordinary credits without exclusions. UNKNOWN pre1951 raw wages remain potentially decisive. | A213(c) grants "one quarter of coverage for each $400" subject to resulting fully insured status; B404.110(c)-(d); RS .315 B.1-B.2 record alternate historical/application conditions. This is an over-approximation for refusal, not a computed deemed-credit answer. A favorable ordinary witness with a higher requirement cannot narrow it. | -| B4. An alternate-pre1956 possibility uses maximum feasible QCs and any eligible 1952Q3–1955Q4 quarter with at least 20 total QCs and every preceding 1951-onward quarter credited, minimum six. Current establishment also requires that quarter to fit every fixed starting bound. | RS .480 A requires "at least 20 quarters of coverage" and "all quarters beginning with 03/51 ... are QCs" with "at least six"; B.1 gives first freeze day 07/01/52 and last 12/31/55. The first possible freeze day is July 1, 1952; an established current period already ended, or observed in force, before then cannot use a later automatic witness. The automatic scan shares the ordinary immutable end/continuity/death/FRA horizon. Unmodeled application restrictions can only remove candidates, so they cannot justify an input error. Explicit specialist flags remain independent possibilities. | +| B4. An alternate-pre1956 possibility uses maximum feasible QCs and any eligible 1952Q3–1955Q4 quarter with at least 20 total QCs and every preceding 1951-onward quarter credited, minimum six, only if lower credits do not already establish 20/40 in its disabled-quarter scan before October 1960. Current establishment also requires the alternate quarter to fit every fixed starting bound. | RS .480 A requires "at least 20 quarters of coverage" and "all quarters beginning with 03/51 ... are QCs" with "at least six", and limits eligibility to workers without 20/40 before 10/60. B.1 gives first freeze day 07/01/52 and last 12/31/55. The first possible freeze day is July 1, 1952; an established current period already ended, or observed in force, before then cannot use a later automatic witness. The automatic scan shares the ordinary immutable end/continuity/death/FRA horizon. The exclusion retains the existing disability scan's FRA-quarter cap for established periods (C321). A lower-credit ordinary 20/40 witness removes the route for all fillings; an upper-only witness leaves it possible. Unmodeled application restrictions can only remove candidates, so they cannot justify an input error. Explicit specialist flags remain independent possibilities. | | B5. Universal recent, fully-prerequisite, and annual count envelopes use zero through maximum feasible ordinary lifetime/year QCs whenever unknown periods/earnings can switch witnesses. | A213(a)(2)(B)(vi) prohibits double credit; B404.146(d) excludes interiors unless disregarded. Every concrete ordinary assignment is a subset of feasible unique lifetime quarters. The envelope permits every witness, even when adding QCs switches to a lower-count witness. Specialist possibilities remain refusals. | | B6. With known earnings and an UNKNOWN ending, returned count bounds include all end-candidate counts admitted by continuity; with entirely known facts they remain exact. | B404.120(b), .130(f), .146(d) distinguish credited endpoints and excluded interiors. All candidate quarters are enumerated, including early endpoints and capped-FRA candidates, subject to any continues-through observation; extrema therefore cover each completion. A continuity date is never inserted as a credited endpoint. No monotonic endpoint-count premise is used. | | B7. DLI lies through query without frozen exit, or through the pre-FRA-quarter/death horizon with frozen coverage; `None` is the bottom bound. A future exit cannot remove query censoring. | RS .148 defines DLI as "the last day in the last quarter" in which status is met and limits the search relative to FRA. B404.146(b) caps credits after death; A216(i)(2)(B) caps new periods. Future undeclared work is not assumed zero. Specialist routes are refused before this ordinary DLI calculation. | @@ -578,7 +623,8 @@ to a statutory sentence that does not state it. | B12. Ordinary counted windows have 13 quarters for current insurance and 40 for ordinary disability; young/subsequent special windows require half their elapsed quarters after dropping an odd remainder, with a six-QC minimum and 20/40 ceiling. | B404.120(a) says "13-quarter period"; .130(b) says "20 QCs in the 40-quarter period"; .130(c)-(d) and A216(i)(3)(B) supply the half-quarter, odd-remainder, and 6/12 alternatives. Blindness uses only the fully insured prerequisite, and pre1956/flagged specialist paths retain refusal rather than being forced through an ordinary window. | | B13. Indexed annual QC amounts are at least the prior year's statutory increment and the rounded indexed 1978 amount, with nearest-$10 rounding and $5 ties upward. | A213(d)(2) chooses "the larger of" the prior increment and indexed amount, rounded to "the next higher multiple of $10" at a $5 tie. This exact parameter calculation has no disability or specialist alternative; input-domain checks require positive NAWI and a statutory prior increment. | | B14. Declaring continuity never widens the administrative-end candidate set; every returned status and count envelope remains valid for every retained concrete ending. | C321(c)'s ending events still govern. Set intersection with ends on/after the observation can only remove candidates; it creates neither an ending nor a new credit. The universal envelope remains unchanged where other unknown facts require it. | -| B15. Ordinary establishment overlap resolution enumerates at most 4,096 unknown-credit fillings after its fixed-date monotonicity check. | C320(b)(2) and C321(a) require one insured beginning consistent with the complete declaration. This is a computational coverage bound. An unresolved search beyond the limit returns `disability_boundary_assignments_unsupported`; it never asserts that a concrete filling exists or proves an input error. | +| B15. Ordinary establishment overlap resolution enumerates at most 4,096 unknown-credit fillings after its fixed-date monotonicity and candidate-quarter exclusion checks. | C320(b)(2) and C321(a) require one insured beginning consistent with the complete declaration. If every possible starting quarter overlaps a supplied prior period, I13 settles impossibility without enumeration. Otherwise this is a computational coverage bound. An unresolved search beyond the limit returns `disability_boundary_assignments_unsupported`; it never asserts that a concrete filling exists or proves an input error. | +| B16. A deferred raw-conversion row retains independently computable ordinary credits in its minimum and every enumerated filling, and cannot exceed feasible calendar-quarter credits in its maximum. | A213(d)(2)'s prior-increment floor bounds future annual credits above by the captured 2027 increment applied to the supplied wages plus SE income; the possibility-only lower bound is zero. Raw 1937 allocation remains zero through four because A213(b)'s half-year rule is unresolved. For separate pre1955 agriculture or pre1951 SE, supported quarterly wage credits and supported post1950 calendar-year SE credits remain fixed; unresolved additional allocation can fill only remaining allowed quarters. Both minimum and maximum fillings may violate derived overlap even when a middle filling is valid, so neither endpoint alone proves impossibility. These bounds do not adjudicate a specialist allocation or replace its refusal. | The round-5 adversarial audit revisits each row in both directions in `scratch/review/round5-premise-audit.md`: a valid filling cannot be rejected, @@ -588,6 +634,15 @@ cap in B4; the wrong-number SS-5 exception and its required possible pre2004 assignment correct I6; continuity adds I11/U9/B14. These are source and interface requirements, with no new statutory reading. +Round 6 additionally checks both directions of refusal deferral (I12/B1), +the alternate test's own 20/40 exclusion (U10/B4), and fixed-quarter overlap +impossibility before a filling limit can apply (I13/B15). Deferred refusals +cannot supply evaluator rows for all-invalid declarations, while a +concrete valid filling retains the named refusal. The 20/40 exclusion +must preserve valid current establishment and possible earliest prior +periods. These changes apply the #530 input contract and captured rules; +they introduce no statutory reading. + The round-5 exactness grid checks both directions against every concrete completion, rather than only checking that rejection is sound. `test_unknown_declaration_exactly_matches_all_concrete_qc_fillings` @@ -613,11 +668,13 @@ Two corners are excluded by name from this exactness claim. Arbitrary UNKNOWN prior history is not exhaustively enumerable in this bounded grid: its earliest-period possibility proof intentionally leaves unobserved administrative histories unresolved, while the explicit -short-DIB fillings test the retained existential witness. Large unresolved -ordinary-overlap searches above 4,096 credit fillings return the named -computational refusal, as pinned by -`test_large_unresolved_overlap_has_explicit_complexity_refusal`; that -refusal asserts neither existence nor impossibility. Specialist +short-DIB fillings test the retained existential witness. Large +ordinary-overlap searches remain excluded only when the fixed +candidate-quarter scan leaves a possible nonoverlapping starting quarter +and more than 4,096 credit fillings are still unresolved. They retain the +named computational refusal; that refusal asserts neither existence nor +impossibility. If every starting quarter overlaps a supplied prior period, +the declaration is invalid even above that filling limit. Specialist administrative adjudication is outside the implemented ordinary surface; the specialist grid checks preservation of a possible route and its denominator, rather than claiming to adjudicate it. No bounded ordinary @@ -717,6 +774,68 @@ Round 5 adds exact classification and administrative continuity: | An adjudicated section 211 exemption preserves the ordinary status/count result and one evaluator row for source-permitted post2003 and never-assigned facts; observed and convention-filled facts have equal statutory treatment. Pre2004-assigned aliens accept exactly the exempt declaration and reject declared applicability. An alien born on/after January 1, 2004 cannot supply the required possible pre2004 assignment and therefore cannot declare exemption. | `test_adjudicated_exemption_preserves_ordinary_count_and_evaluator_row`, `test_pre2004_assignment_accepts_exactly_the_exempt_applicability`, `test_wrong_number_exemption_requires_possible_pre2004_assignment` | | A continuity declaration never widens the candidate-ending set. Every returned status and count envelope agrees with or contains every retained concrete ending; no continuity observation becomes a credited endpoint. | `test_continuity_only_narrows_candidates_and_all_concrete_ends_agree` | +Round 6 adds refusal ordering and settled route exclusions: + +| Invariant | Executing tests | +| --- | --- | +| Adding any of the four early raw-conversion refusal facts where it cannot change an all-invalid declaration preserves `InvalidFamilyInput`, zero rows, and zero weight, independently of mapping order. Placing it where concrete credit fillings can validate the declaration preserves the original refusal reason and note. Multiple deferred reasons retain sorted-year priority, including when an overlap search reaches its coverage limit. | `test_irrelevant_early_refusal_fact_preserves_all_invalid_grid_case`; `test_every_early_qc_refusal_preserves_possible_declaration`; `test_deferred_refusals_keep_original_sorted_year_priority`; `test_unresolved_overlap_keeps_original_deferred_refusal` | +| An unsupported future increment cannot hide a fixed earlier impossible end, for zero, one, or 10,000 raw wage dollars, including the age-62 and coverage-exit interfaces. The captured increment floor can prove too few possible credits; a sufficient possible filling keeps the original refusal. All schema/history errors still precede deferred refusals. | `test_unrelated_uncaptured_increment_cannot_hide_impossible_fixed_end`; `test_uncaptured_increment_bounds_preserve_both_classifications`; `test_schema_validation_precedes_deferred_qc_refusals` | +| A lower-credit 20/40 witness before October 1960 makes the automatic alternate unavailable under every added unknown-credit filling. The scan includes later disabled quarters and 1960Q3, excludes 1960Q4 and witnesses after the FRA quarter for established periods, and does not substitute blindness or the young-worker rule for 20/40. An upper-only witness preserves the alternate refusal and evaluator row. | `test_fixed_twenty_of_forty_exclusion_survives_extra_unknown_credits`; `test_twenty_of_forty_before_october_1960_excludes_alternate_refusal`; `test_twenty_of_forty_scan_includes_later_disabled_quarters_before_1960`; `test_twenty_of_forty_alternate_exclusion_stops_before_october_1960`; `test_alternate_exclusion_uses_existing_disability_scan_fra_boundary`; `test_other_ordinary_disability_routes_do_not_supply_twenty_of_forty`; `test_some_twenty_of_forty_fillings_keep_named_alternate_refusal` | +| Excluding an unavailable alternate does not reject an ordinary current establishment or prove possible nonempty prior history empty. | `test_excluding_alternate_preserves_ordinary_current_establishment`; `test_excluding_alternate_preserves_possible_nonempty_prior_history` | +| If every possible starting quarter overlaps a supplied prior quarter, changing credit uncertainty cannot create a valid establishment or a refusal row, even above the filling limit. A neighboring nonoverlapping valid filling remains possible and retains the earnings refusal. | `test_immutable_overlap_is_independent_of_credit_uncertainty`; `test_fixed_same_quarter_overlap_precedes_large_filling_refusal`; `test_large_overlap_neighbour_keeps_valid_filling` | +| Deferred historical-credit fillings retain every independently guaranteed quarter. A valid middle filling prevents rejection even when both endpoints are invalid; fixing an overlapping first quarter can instead make every admissible filling invalid. Mapping order changes neither conclusion. | `test_deferred_quarter_fillings_keep_fixed_minimum_and_valid_middle` | + +The round-6 ordering example has birth February 2, 2000, onset January 15, +2022, observed establishment ending January 31, 2022, observed exemption +and empty prior history, zero QCs through 2027, and raw 2028 wages. At the +January 2028 FULLY query, raw wages of $0, $1, or $10,000 cannot change the +zero-QC insured-start history through the declared end. Each call raises +`InvalidFamilyInput` with no row or weight; every direct 2028 count from +zero through four does too. Birth February 2, 1965 and a declared January +2028 coverage exit preserve this conclusion. Conversely, a blind worker +born February 2, 2000, with January 15, 2028 onset, a December 2028 ending, +four QCs in 2026 and one in 2027, could establish a period if 2028 supplies +the sixth credit. Raw 2028 wages of $10,000 therefore retain +`qc_amount_year_unsupported` and the evaluator's weight 3/2. The other +three conversion reasons receive the same irrelevant/relevant-filling +checks. This applies C320(b)(2), C321(a), and the #530 input contract. + +For the settled historical route, birth February 2, 1920, onset January +15, 1955, and all four quarters credited in each of 1950–1954 supply 20/40 +at onset. All other 1937–1968 quarters are explicitly uncredited. The +January 1968 FULLY result is insured, with current start January 15, 1955; +RS .480 A excludes its alternate and application facts need not be guessed. +Moving the four 1950 credits to 1940 and supplying four in 1956 instead +gives an ordinary October 1, 1956 start, still within the exclusion scan. +With 1950 UNKNOWN and the extra four 1940 credits, enumeration finds one +ordinary filling and fifteen alternate-refused fillings; the UNKNOWN +declaration preserves `disability_before_1956_unsupported` and weight 11/5. + +For the fixed-overlap example, birth February 2, 1940, onset February 15, +1977, a supplied January 1, 1970–January 31, 1977 prior period, and a March +31, 1977 current end leave only 1977Q1 as a current starting quarter. Four +QCs in each of 1968 and 1969, UNKNOWN 1974–1977, and zeros elsewhere cannot +clear that prior ending quarter. The January 1978 FULLY query raises +`InvalidFamilyInput` before the 8,192 combinations could trigger the +4,096-filling limit and create a row. +Moving only the prior ending to December 31, 1976 admits a valid filling: +all four quarters credited in each UNKNOWN year give an insured ordinary +current start on February 15, 1977. The UNKNOWN declaration therefore +retains `unknown_earnings_years_decide_status` (C320(b)(2); C321(a)). + +A deferred-allocation control has birth February 2, 1920, onset February +15, 1954, a July 15, 1952–January 31, 1954 prior period, current end +December 31, 1954, and January 1968 FULLY query, with observed facts. +Credits are one in 1938, +four in each of 1946–1948, one in 1949, four in 1951, and two in 1952; +other years are zero. The prior has RS .480's 20 lifetime and six +continuous credits. Of the 16 concrete 1954 masks, both all-zero and +all-four are invalid; the seven with Q1 uncredited and some later credit +are valid. Raw agricultural wages of $100 preserve +`pre1955_agricultural_allocation_unsupported`. Adding $50 of independently +credited Q1 nonagricultural wages +requires Q1 in every filling: all eight are invalid and create no row. + The fixed-end example has birth February 2, 2000, medical onset January 15, 2022, observed establishment, a January 31, 2022 declared end, four QCs in 2021, UNKNOWN 2022 credits, and zeros elsewhere. At an April 2022 @@ -909,7 +1028,7 @@ RS .149 links an uncaptured worksheet, which is not represented as read. RS .340 prints $10,900 in SEI but allocates $3,600 to each of three quarters. Literal covered SEI divides as $10,900/3. An unstated application -of the1973 taxable ceiling of $10,800 instead reproduces $3,600 exactly, +of the 1973 taxable ceiling of $10,800 instead reproduces $3,600 exactly, if $10,900 meant net earnings before that ceiling. Tests execute both readings; both give three QCs. The public short-year path remains refused. RS .345 prints an impossible “after 1975 and before 1975” SE fiscal bracket; the calendar 1975 maximum of $14,100 is independently @@ -996,6 +1115,9 @@ Short DIB-entitled periods, earlier administrative endings, the alternate pre1956 test, and the wrong-number SS-5 exemption are captured source requirements. Dated observed continuity supplies a missing input; it is not a new statutory reading. They introduce no additional question for Max. +Round 6's deferred raw-credit refusals implement the #530 input contract; +the alternate-route exclusion and fixed-quarter overlap apply captured +RS .480 A, C320(b)(2), and C321(a). They add no reading for the orchestrator. Mutation checks are recorded in [`track_b_insured_status_mutations.json`](track_b_insured_status_mutations.json). diff --git a/docs/design/track_b_insured_status_mutations.json b/docs/design/track_b_insured_status_mutations.json index bf8121d31..7eba0e175 100644 --- a/docs/design/track_b_insured_status_mutations.json +++ b/docs/design/track_b_insured_status_mutations.json @@ -2082,5 +2082,225 @@ } ], "round_5_note": "Ordinary fixed-date and same-filling validity, source-permitted SSPA exemptions and retained birth/assignment contradictions, continuity candidate intersection and validation, and automatic historical/FRA chronology. Every deliberate mutation was caught and discarded or reverted; no existing test assertion was weakened.", - "round_5_final_source_sha256": "04964886c402b0ff44dd958fa0b82b6055730f463fdf660a6e346999e13fd493" + "round_5_final_source_sha256": "04964886c402b0ff44dd958fa0b82b6055730f463fdf660a6e346999e13fd493", + "round_6_mutations": [ + { + "name": "conversion_refusal_before_impossibility", + "before": "deferred[year] = error", + "after": "raise error", + "pytest_selector": "tests/test_track_b_insured_status_fix_round_6_ordering.py::test_unrelated_uncaptured_increment_cannot_hide_impossible_fixed_end[False-0-birth0]", + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_6_ordering.py::test_unrelated_uncaptured_increment_cannot_hide_impossible_fixed_end[False-0-birth0]" + ], + "summary": [ + "1 failed in 18.84s" + ], + "restored": true, + "method": "Isolated in-memory module mutation; implementation file never changed.", + "environment": { + "PYTHONPATH": "$PWD/src:$PWD", + "OMP_NUM_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/trackb-round6", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/trackb-round6" + }, + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round6 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round6 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\nbefore = 'deferred[year] = error'\nafter = 'raise error'\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', '--tb=short', 'tests/test_track_b_insured_status_fix_round_6_ordering.py::test_unrelated_uncaptured_increment_cannot_hide_impossible_fixed_end[False-0-birth0]'])\nassert Path(i.__file__).read_text() == original\nraise SystemExit(result)\nPY" + }, + { + "name": "drop_nondecreasing_increment_bound", + "before": "2027,\n row.wages", + "after": "1978,\n row.wages", + "pytest_selector": "tests/test_track_b_insured_status_fix_round_6_ordering.py::test_uncaptured_increment_bounds_preserve_both_classifications[3939]", + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_6_ordering.py::test_uncaptured_increment_bounds_preserve_both_classifications[3939]" + ], + "summary": [ + "1 failed in 13.12s" + ], + "restored": true, + "method": "Isolated in-memory module mutation; implementation file never changed.", + "environment": { + "PYTHONPATH": "$PWD/src:$PWD", + "OMP_NUM_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/trackb-round6", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/trackb-round6" + }, + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round6 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round6 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\nbefore = '2027,\\n row.wages'\nafter = '1978,\\n row.wages'\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', '--tb=short', 'tests/test_track_b_insured_status_fix_round_6_ordering.py::test_uncaptured_increment_bounds_preserve_both_classifications[3939]'])\nassert Path(i.__file__).read_text() == original\nraise SystemExit(result)\nPY" + }, + { + "name": "exclude_alternate_using_upper_filling", + "before": "lower = credits if lower_credits is None else lower_credits", + "after": "lower = credits", + "pytest_selector": "tests/test_track_b_insured_status_fix_round_6_routes.py::test_some_twenty_of_forty_fillings_keep_named_alternate_refusal", + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_6_routes.py::test_some_twenty_of_forty_fillings_keep_named_alternate_refusal" + ], + "summary": [ + "1 failed in 21.02s" + ], + "restored": true, + "method": "Isolated in-memory module mutation; implementation file never changed.", + "environment": { + "PYTHONPATH": "$PWD/src:$PWD", + "OMP_NUM_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/trackb-round6", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/trackb-round6" + }, + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round6 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round6 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\nbefore = 'lower = credits if lower_credits is None else lower_credits'\nafter = 'lower = credits'\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', '--tb=short', 'tests/test_track_b_insured_status_fix_round_6_routes.py::test_some_twenty_of_forty_fillings_keep_named_alternate_refusal'])\nassert Path(i.__file__).read_text() == original\nraise SystemExit(result)\nPY" + }, + { + "name": "include_october_1960_in_exclusion", + "before": "min(_qid(month), 1960 * 4 + 2)", + "after": "min(_qid(month), 1960 * 4 + 3)", + "pytest_selector": "tests/test_track_b_insured_status_fix_round_6_routes.py::test_twenty_of_forty_alternate_exclusion_stops_before_october_1960", + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_6_routes.py::test_twenty_of_forty_alternate_exclusion_stops_before_october_1960[4]" + ], + "summary": [ + "1 failed, 1 passed in 20.12s" + ], + "restored": true, + "method": "Isolated in-memory module mutation; implementation file never changed.", + "environment": { + "PYTHONPATH": "$PWD/src:$PWD", + "OMP_NUM_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/trackb-round6", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/trackb-round6" + }, + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round6 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round6 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\nbefore = 'min(_qid(month), 1960 * 4 + 2)'\nafter = 'min(_qid(month), 1960 * 4 + 3)'\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', '--tb=short', 'tests/test_track_b_insured_status_fix_round_6_routes.py::test_twenty_of_forty_alternate_exclusion_stops_before_october_1960'])\nassert Path(i.__file__).read_text() == original\nraise SystemExit(result)\nPY" + }, + { + "name": "skip_immutable_quarter_overlap", + "before": "if person.prior_disability_periods and not any(", + "after": "if False and not any(", + "pytest_selector": "tests/test_track_b_insured_status_fix_round_6_routes.py::test_fixed_same_quarter_overlap_precedes_large_filling_refusal", + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_6_routes.py::test_fixed_same_quarter_overlap_precedes_large_filling_refusal" + ], + "summary": [ + "1 failed in 14.63s" + ], + "restored": true, + "method": "Isolated in-memory module mutation; implementation file never changed.", + "environment": { + "PYTHONPATH": "$PWD/src:$PWD", + "OMP_NUM_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/trackb-round6", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/trackb-round6" + }, + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round6 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round6 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\nbefore = 'if person.prior_disability_periods and not any('\nafter = 'if False and not any('\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', '--tb=short', 'tests/test_track_b_insured_status_fix_round_6_routes.py::test_fixed_same_quarter_overlap_precedes_large_filling_refusal'])\nassert Path(i.__file__).read_text() == original\nraise SystemExit(result)\nPY" + }, + { + "name": "omit_deferred_overlap_fillings", + "before": "or year in deferred_years", + "after": "or False", + "pytest_selector": "tests/test_track_b_insured_status_fix_round_6_ordering.py::test_deferred_quarter_fillings_keep_fixed_minimum_and_valid_middle", + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_6_ordering.py::test_deferred_quarter_fillings_keep_fixed_minimum_and_valid_middle" + ], + "summary": [ + "1 failed in 129.36s (0:02:09)" + ], + "restored": true, + "method": "Isolated in-memory module mutation; implementation file never changed.", + "environment": { + "PYTHONPATH": "$PWD/src:$PWD", + "OMP_NUM_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/trackb-round6", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/trackb-round6" + }, + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round6 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round6 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\nbefore = 'or year in deferred_years'\nafter = 'or False'\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', '--tb=short', 'tests/test_track_b_insured_status_fix_round_6_ordering.py::test_deferred_quarter_fillings_keep_fixed_minimum_and_valid_middle'])\nassert Path(i.__file__).read_text() == original\nraise SystemExit(result)\nPY" + }, + { + "name": "drop_guaranteed_quarter_minimum", + "before": "fixed = tuple(q for q in lower[year][0] if q in allowed)", + "after": "fixed = ()", + "pytest_selector": "tests/test_track_b_insured_status_fix_round_6_ordering.py::test_deferred_quarter_fillings_keep_fixed_minimum_and_valid_middle", + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_6_ordering.py::test_deferred_quarter_fillings_keep_fixed_minimum_and_valid_middle" + ], + "summary": [ + "1 failed in 105.17s (0:01:45)" + ], + "restored": true, + "method": "Isolated in-memory module mutation; implementation file never changed.", + "environment": { + "PYTHONPATH": "$PWD/src:$PWD", + "OMP_NUM_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/trackb-round6", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/trackb-round6" + }, + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round6 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round6 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\nbefore = 'fixed = tuple(q for q in lower[year][0] if q in allowed)'\nafter = 'fixed = ()'\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', '--tb=short', 'tests/test_track_b_insured_status_fix_round_6_ordering.py::test_deferred_quarter_fillings_keep_fixed_minimum_and_valid_middle'])\nassert Path(i.__file__).read_text() == original\nraise SystemExit(result)\nPY" + }, + { + "name": "replace_original_refusal_with_complexity", + "before": "raise next(iter(deferred.values())) from None", + "after": "raise", + "pytest_selector": "tests/test_track_b_insured_status_fix_round_6_ordering.py::test_unresolved_overlap_keeps_original_deferred_refusal", + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_6_ordering.py::test_unresolved_overlap_keeps_original_deferred_refusal" + ], + "summary": [ + "1 failed in 20.20s" + ], + "restored": true, + "method": "Isolated in-memory module mutation; implementation file never changed.", + "environment": { + "PYTHONPATH": "$PWD/src:$PWD", + "OMP_NUM_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/trackb-round6", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/trackb-round6" + }, + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round6 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round6 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\nbefore = 'raise next(iter(deferred.values())) from None'\nafter = 'raise'\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', '--tb=short', 'tests/test_track_b_insured_status_fix_round_6_ordering.py::test_unresolved_overlap_keeps_original_deferred_refusal'])\nassert Path(i.__file__).read_text() == original\nraise SystemExit(result)\nPY" + }, + { + "name": "ignore_established_period_fra_scan_boundary", + "before": "and quarter > _fra_quarter(person)", + "after": "and False", + "pytest_selector": "tests/test_track_b_insured_status_fix_round_6_routes.py::test_alternate_exclusion_uses_existing_disability_scan_fra_boundary[3]", + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_6_routes.py::test_alternate_exclusion_uses_existing_disability_scan_fra_boundary[3]" + ], + "summary": [ + "1 failed in 23.12s" + ], + "restored": true, + "method": "Isolated in-memory module mutation; implementation file never changed.", + "environment": { + "PYTHONPATH": "$PWD/src:$PWD", + "OMP_NUM_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/trackb-round6", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/trackb-round6" + }, + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round6 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round6 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\nbefore = 'and quarter > _fra_quarter(person)'\nafter = 'and False'\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', '--tb=short', 'tests/test_track_b_insured_status_fix_round_6_routes.py::test_alternate_exclusion_uses_existing_disability_scan_fra_boundary[3]'])\nassert Path(i.__file__).read_text() == original\nraise SystemExit(result)\nPY" + } + ], + "round_6_note": "Nine isolated in-memory implementation mutations were caught and discarded against the final source. No implementation mutation was written to disk; every child verified the final source SHA-256 stayed unchanged. The original sorted-year conversion refusal, bounded unknown fillings, fixed quarterly minimum, lower-credit 20/40 exclusion with its existing FRA boundary and October 1960 cutoff, and immutable overlap check remain enforced. No existing test assertion was weakened.", + "round_6_final_source_sha256": "223fb5e5b436a12b049d948c9cfdcf9827c606f403ab5ae419a37e2024dc174f" } diff --git a/src/populace_dynamics/track_b/insured_status.py b/src/populace_dynamics/track_b/insured_status.py index 0bb17757d..dd066dcb2 100644 --- a/src/populace_dynamics/track_b/insured_status.py +++ b/src/populace_dynamics/track_b/insured_status.py @@ -717,7 +717,7 @@ def _coverage_checks(person, years, month, credits): def _observable_coverage_paths( - person, years, month, exit_month, kind, lo, upper + person, years, month, exit_month, kind, lo, upper, lower ): """Refuse favorable specialist paths revealed by ordinary declarations. @@ -784,7 +784,7 @@ def _observable_coverage_paths( "Act213(c); filing and retroactivity facts are unmodeled", ) elif kind is InsuredTest.DISABILITY and _pre1956_alternate_possible( - person, upper, month, exit_month + person, upper, month, exit_month, lower_credits=lower ): _refuse( InsuredUnsupportedReason.DISABILITY_BEFORE_1956, @@ -793,12 +793,41 @@ def _observable_coverage_paths( ) -def _pre1956_alternate_possible(person, credits, month, exit_month): +def _pre1956_alternate_possible( + person, credits, month, exit_month, *, lower_credits=None +): """RS00301.480 possibility, without guessing filing eligibility.""" if person.disability_onset is None or person.disability_onset >= date( 1956, 1, 1 ): return False + # RS00301.480 A excludes anyone with 20/40 in any disabled quarter + # before October 1960. Only the lower filling can exclude every + # completion. Use the ordinary disability window, including favorable + # consideration or disregard of all prior periods (404.130(f)). + lower = credits if lower_credits is None else lower_credits + for quarter in range( + _qid(person.disability_onset), min(_qid(month), 1960 * 4 + 2) + 1 + ): + # Use the established-period disability scan's FRA boundary. + if ( + person.current_disability_period_established + and quarter > _fra_quarter(person) + ): + break + for use_periods in ( + (True, False) if person.prior_disability_periods else (True,) + ): + rows, periods = _world( + person, lower, quarter, exit_month, use_periods + ) + for boundary in _boundary_variants(rows, periods): + window = _window(quarter, 40, periods, boundary) + if ( + len(set(_assignment(rows, window, boundary)) & set(window)) + >= 20 + ): + return False if person.current_disability_period_established: # RS00301.480 B.1: a freeze cannot begin before 1952-07-01. # An independent alternate route still must start before the @@ -855,6 +884,32 @@ def _credits(year, row, upper): _refuse(InsuredUnsupportedReason(error.reason), str(error)) +def _deferred_credit_bounds(year, row): + """Possibility-only bounds; never replace a refused ordinary result.""" + if year > 2027: + # Act 213(d)(2): an increment cannot fall below captured 2027's. + return ((), 0), ( + (), + _post1977_qc_count( + 2027, + row.wages or Fraction(0), + row.self_employment or Fraction(0), + ), + ) + if year == 1937: + # Act 213(b)'s half-year allocation prevents fixing raw wage slots. + return ((), 0), ((), 4) + # Unsupported annual AG/SE allocation cannot remove independently + # credited ordinary wages or supported calendar-year SE quarters. + fixed, flexible = _pre1978_qc_credits( + year, + row.quarterly_wages or (Fraction(0),) * 4, + (row.self_employment or Fraction(0)) if year >= 1951 else Fraction(0), + Fraction(0), + ) + return (fixed, flexible), (fixed, 4 - len(fixed)) + + def _world( person, credits, @@ -1059,7 +1114,9 @@ def _witness(person, credits, at, exit_month, kind, *, onset=True): return best[1] -def _unknown_prior_history_is_empty(person, credits, month, exit_month): +def _unknown_prior_history_is_empty( + person, credits, month, exit_month, *, lower_credits=None +): """Prove infeasibility of the earliest nonempty prior period only. The earliest period must begin insured without any earlier exclusions @@ -1112,7 +1169,11 @@ def _unknown_prior_history_is_empty(person, credits, month, exit_month): current_disability_period_continues_through_convention_id=None, ) if _pre1956_alternate_possible( - possible_prior, credits, start, exit_month + possible_prior, + credits, + start, + exit_month, + lower_credits=lower_credits, ): return False if _witness( @@ -1329,7 +1390,7 @@ def _current_period_start_horizon(person, month): def _specialist_establishment_possible( - person, years, credits, month, exit_month + person, years, credits, month, exit_month, *, lower_credits=None ): """Overapproximate flagged/observable alternatives to ordinary insurance. @@ -1348,11 +1409,21 @@ def _specialist_establishment_possible( ): continue return True - return _pre1956_alternate_possible(person, credits, month, exit_month) + return _pre1956_alternate_possible( + person, credits, month, exit_month, lower_credits=lower_credits + ) def _could_establish_current_period( - person, years, credits, month, exit_month, maximum_qcs + person, + years, + credits, + month, + exit_month, + maximum_qcs, + *, + lower_credits=None, + deferred_years=(), ): """Reject only a declaration impossible under every possible route. @@ -1361,18 +1432,27 @@ def _could_establish_current_period( prior-quarter overlap must be cleared by that same concrete filling. Calendar/schema contradictions have already been rejected. Ordinary premises cannot exclude a specialist route or a short DIB-entitled - prior period. Unresolved prior histories and more than 4096 overlap - fillings remain explicitly outside the exact ordinary predicate. + prior period. Fixed quarter overlap is checked before searching. + Unresolved prior histories and more than 4096 overlap fillings that + survive that check remain outside the exact ordinary predicate. """ if not person.current_disability_period_established: return True + horizon = _current_period_start_horizon(person, month) + if person.prior_disability_periods and not any( + all( + not _qid(period.start) <= quarter <= _qid(period.end) + for period in person.prior_disability_periods + ) + for quarter in range(_qid(person.disability_onset), _qid(horizon) + 1) + ): + return False if _specialist_establishment_possible( - person, years, credits, month, exit_month + person, years, credits, month, exit_month, lower_credits=lower_credits ): return True if maximum_qcs < 6: return False - horizon = _current_period_start_horizon(person, month) rows, _ = _world(person, credits, _qid(horizon), exit_month, False) if sum(len(_assign_qcs(*row)) for row in rows.values()) < 6: return False @@ -1380,7 +1460,7 @@ def _could_establish_current_period( person.prior_disability_periods_provenance is EarningsProvenance.UNKNOWN and not _unknown_prior_history_is_empty( - person, credits, month, exit_month + person, credits, month, exit_month, lower_credits=lower_credits ) ): return True @@ -1405,13 +1485,17 @@ def _could_establish_current_period( unknown = tuple( year for year, row in sorted(years.items()) - if row.provenance is EarningsProvenance.UNKNOWN + if ( + row.provenance is EarningsProvenance.UNKNOWN + or year in deferred_years + ) and year <= horizon.year ) if not unknown: return False - lower = dict(credits) - lower.update({year: ((), 0) for year in unknown}) + lower = dict(credits if lower_credits is None else lower_credits) + if lower_credits is None: + lower.update({year: ((), 0) for year in unknown}) try: _with_current_period(plain, lower, horizon, exit_month) except InvalidFamilyInput: @@ -1425,22 +1509,34 @@ def _could_establish_current_period( for year in unknown: allowed = rows.get(year, ((), 0, ()))[2] if year < 1978: + fixed = tuple(q for q in lower[year][0] if q in allowed) + vacant = tuple(q for q in allowed if q not in fixed) options.append( tuple( ( tuple( - q - for q, flag in zip(allowed, flags, strict=True) - if flag + sorted( + fixed + + tuple( + q + for q, flag in zip( + vacant, flags, strict=True + ) + if flag + ) + ) ), 0, ) - for flags in product((False, True), repeat=len(allowed)) + for flags in product((False, True), repeat=len(vacant)) ) ) else: options.append( - tuple(((), count) for count in range(len(allowed) + 1)) + tuple( + ((), count) + for count in range(min(len(allowed), credits[year][1]) + 1) + ) ) if prod(map(len, options)) > 4096: _refuse( @@ -1492,13 +1588,22 @@ def insured_status( query, and the first insured quarter supplies the witness (404.131). Establishment is an input error only if no ordinary, observable, or flagged specialist route could validate any completion of the facts. + History validation runs first. Uncomputable QC rows use bounded + unknown credits only for this proof; a possible declaration retains + its original conversion refusal, including its reason and detail. No entry date, imputation, or pre-entry zero convention exists. """ _validate_history( person, years, month, coverage_end_month, totalization_credits ) - lower = {y: _credits(y, row, False) for y, row in sorted(years.items())} - upper = {y: _credits(y, row, True) for y, row in sorted(years.items())} + lower, upper, deferred = {}, {}, {} + for year, row in sorted(years.items()): + try: + lower[year] = _credits(year, row, False) + upper[year] = _credits(year, row, True) + except InsuredConfigurationUnsupported as error: + deferred[year] = error + lower[year], upper[year] = _deferred_credit_bounds(year, row) unknown = tuple( y for y, row in sorted(years.items()) @@ -1524,17 +1629,32 @@ def insured_status( include_zero=True, ) maximum_qcs = sum(len(_assign_qcs(*row)) for row in max_rows.values()) - if not _could_establish_current_period( - person, years, upper, month, coverage_end_month, maximum_qcs - ): + try: + possible = _could_establish_current_period( + person, + years, + upper, + month, + coverage_end_month, + maximum_qcs, + lower_credits=lower, + deferred_years=tuple(deferred), + ) + except InsuredConfigurationUnsupported: + if deferred: + raise next(iter(deferred.values())) from None + raise + if not possible: raise InvalidFamilyInput( "Established current period has no possible insured disabled quarter" ) + if deferred: + raise next(iter(deferred.values())) _coverage_checks(person, years, month, totalization_credits) if ( person.current_disability_period_established and _pre1956_alternate_possible( - person, upper, month, coverage_end_month + person, upper, month, coverage_end_month, lower_credits=lower ) ): _refuse( @@ -1663,7 +1783,14 @@ def insured_status( decision_lo_people, lo_candidates, strict=True ): _observable_coverage_paths( - p, years, month, coverage_end_month, kind, witness, upper + p, + years, + month, + coverage_end_month, + kind, + witness, + upper, + lower, ) if lo[0] != hi[0]: _refuse( diff --git a/tests/README-tiers.md b/tests/README-tiers.md index db823dc6c..61b3ae1e1 100644 --- a/tests/README-tiers.md +++ b/tests/README-tiers.md @@ -39,9 +39,9 @@ pytest --collect-only -q -m oracle_policyengine | tail -1 | Tier | Tests at HEAD | |---|---:| -| `unit` | 20,585 | +| `unit` | 20,640 | | `artifact` | 4,271 | | `integration_psid` | 1,471 | | `reproduction_legacy` | 520 | | `oracle_policyengine` | 308 | -| **Total** | **27,155** | +| **Total** | **27,210** | diff --git a/tests/test_track_b_insured_status_fix_round_6_ordering.py b/tests/test_track_b_insured_status_fix_round_6_ordering.py new file mode 100644 index 000000000..3957496e1 --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_6_ordering.py @@ -0,0 +1,291 @@ +"""Statutory conformance: input errors precede unrelated QC refusals. + +Invented declarations only; no population, behavioral, or forecast claim. +""" + +from dataclasses import replace +from datetime import date +from fractions import Fraction +from itertools import product + +import pytest +from hypothesis import given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as i +from populace_dynamics.track_b.gross_benefits import count_family_outcomes +from tests.test_track_b_insured_status import declared, history +from tests.test_track_b_insured_status_fix_round_4_routes import ( + _prior_overlap_unknown_earnings_case, +) +from tests.test_track_b_insured_status_fix_round_5_possibility import ( + _classification, + _fixed_end_case, +) + +OBSERVED = i.EarningsProvenance.OBSERVED + + +def _evaluate(person, years, month, **kwargs): + return i.evaluate_insured_status( + "deferred-qc", + Fraction(3, 2), + lambda: i.insured_status( + person, years, month, test=i.InsuredTest.FULLY, **kwargs + ), + ) + + +def _no_row(person, years, month, **kwargs): + rows = [] + with pytest.raises(i.InvalidFamilyInput): + rows.append(_evaluate(person, years, month, **kwargs)) + denominator = count_family_outcomes(rows) + assert denominator.rows == denominator.unsupported_rows == 0 + assert denominator.weight == denominator.unsupported_weight == 0 + + +@pytest.mark.parametrize("birth", [date(2000, 2, 2), date(1965, 2, 2)]) +@pytest.mark.parametrize("wages", [0, 1, 10000]) +@pytest.mark.parametrize("exit_declared", [False, True]) +def test_unrelated_uncaptured_increment_cannot_hide_impossible_fixed_end( + birth, wages, exit_declared +): + person, _, _ = _fixed_end_case(previous=0) + person = replace(person, birth_date=birth) + month = date(2028, 1, 1) + years = history(person, month) + for count in range(5): + _no_row(person, {**years, 2028: declared(count)}, month) + years[2028] = i.CoverageYear(OBSERVED, wages=Fraction(wages)) + kwargs = {"coverage_end_month": month} if exit_declared else {} + _no_row(person, years, month, **kwargs) + + +EARLY = ( + (2028, {"wages": Fraction(10000)}, i.InsuredUnsupportedReason.QC_YEAR), + ( + 1937, + {"quarterly_wages": (Fraction(50),) * 4}, + i.InsuredUnsupportedReason.EARNINGS_1937, + ), + ( + 1950, + {"self_employment": Fraction(400)}, + i.InsuredUnsupportedReason.PRE1951_SELF_EMPLOYMENT, + ), + ( + 1953, + {"agricultural_wages": Fraction(400)}, + i.InsuredUnsupportedReason.PRE1955_AGRICULTURE, + ), +) + + +def _early_case(year, *, relevant): + if year == 2028: + birth, onset, end, counts = ( + date(2000, 2, 2), + date(2028, 1, 15), + date(2028, 12, 31), + {2026: 4, 2027: 1}, + ) + else: + birth = date(1930, 2, 2) + onset = date(1952, 7, 15) if year < 1952 else date(year + 1, 4, 15) + end = date(onset.year, 12, 31) + counts = {1951 if year < 1952 else year + 1: 2} + if not relevant: + # A January ending with at most one ordinary quarter cannot be + # established; later facts cannot repair that immutable bound. + onset, end, counts = birth, date(birth.year, 2, 28), {} + person = i.Person( + birth, + disability_onset=onset, + statutory_blindness=True, + current_disability_period_established=True, + current_disability_period_provenance=OBSERVED, + current_disability_period_end=end, + current_disability_period_end_provenance=OBSERVED, + prior_disability_periods_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + month = date(2028, 12, 1) if year == 2028 else date(1973, 1, 1) + return person, history(person, month, counts), month + + +@pytest.mark.parametrize("year,values,reason", EARLY) +def test_every_early_qc_refusal_preserves_possible_declaration( + year, values, reason +): + person, years, month = _early_case(year, relevant=True) + if year < 1978: + concrete = [ + {**years, year: i.CoverageYear(OBSERVED, qc_quarters=flags)} + for flags in product((False, True), repeat=4) + ] + else: + concrete = [{**years, year: declared(n)} for n in range(5)] + fillings = [_classification(person, filled, month) for filled in concrete] + assert any(fillings) + assert not all(fillings) + row = _evaluate( + person, {**years, year: i.CoverageYear(OBSERVED, **values)}, month + ) + assert row.unsupported.reason is reason + assert count_family_outcomes((row,)).unsupported_weight == Fraction(3, 2) + # Deferred conversion keeps the original reason and explanatory note. + with pytest.raises(i.InsuredConfigurationUnsupported) as error: + i._credits(year, i.CoverageYear(OBSERVED, **values), False) + assert row.unsupported.detail == error.value.detail + + +@settings(max_examples=12, deadline=None) +@given(index=st.integers(0, len(EARLY) - 1), reverse=st.booleans()) +def test_irrelevant_early_refusal_fact_preserves_all_invalid_grid_case( + index, reverse +): + year, values, _ = EARLY[index] + if year == 2028: + person, _, _ = _fixed_end_case(previous=0) + month = date(2028, 12, 1) + years = history(person, month, {2021: 4}) + else: + person, years, month = _early_case(year, relevant=False) + # Start with an all-invalid exactness-grid declaration, then add the + # coverage fact. Every concrete filling still produces no row. + assert not _classification(person, years, month) + years[year] = i.CoverageYear(OBSERVED, **values) + if reverse: + years = dict(reversed(tuple(years.items()))) + _no_row(person, years, month) + test_every_early_qc_refusal_preserves_possible_declaration( + year, values, EARLY[index][2] + ) + + +@pytest.mark.parametrize("wages", [0, 1, 3939, 3940, 10000]) +def test_uncaptured_increment_bounds_preserve_both_classifications(wages): + person, _, _ = _fixed_end_case(previous=0) + person = replace( + person, + statutory_blindness=True, + disability_onset=date(2028, 1, 15), + current_disability_period_end=date(2028, 6, 30), + ) + month = date(2028, 12, 1) + years = history(person, month, {2027: 4}) + years[2028] = i.CoverageYear(OBSERVED, wages=Fraction(wages)) + if wages < 3940: + _no_row(person, years, month) + else: + row = _evaluate(person, years, month) + assert row.unsupported.reason is i.InsuredUnsupportedReason.QC_YEAR + + +@pytest.mark.parametrize("reverse", [False, True]) +def test_deferred_refusals_keep_original_sorted_year_priority(reverse): + person, years, month = _early_case(1950, relevant=True) + years[1937] = i.CoverageYear(OBSERVED, quarterly_wages=(Fraction(50),) * 4) + years[1950] = i.CoverageYear(OBSERVED, self_employment=Fraction(400)) + if reverse: + years = dict(reversed(tuple(years.items()))) + row = _evaluate(person, years, month) + assert row.unsupported.reason is i.InsuredUnsupportedReason.EARNINGS_1937 + assert row.unsupported.detail == "1937_earnings_allocation_unsupported" + + +def test_unresolved_overlap_keeps_original_deferred_refusal(): + person, years, month = _prior_overlap_unknown_earnings_case() + person = replace( + person, + current_disability_period_end=date(1972, 12, 31), + current_disability_period_end_provenance=OBSERVED, + ) + for year in range(1965, 1971): + years[year] = i.CoverageYear(i.EarningsProvenance.UNKNOWN) + years[1937] = i.CoverageYear(OBSERVED, quarterly_wages=(Fraction(50),) * 4) + row = _evaluate(person, years, month) + assert row.unsupported.reason is i.InsuredUnsupportedReason.EARNINGS_1937 + assert row.unsupported.detail == "1937_earnings_allocation_unsupported" + + +@settings(max_examples=4, deadline=None) +@given(fixed_first=st.booleans(), reverse=st.booleans()) +def test_deferred_quarter_fillings_keep_fixed_minimum_and_valid_middle( + fixed_first, reverse +): + person = i.Person( + date(1920, 2, 2), + disability_onset=date(1954, 2, 15), + prior_disability_periods=( + i.DisabilityPeriod(date(1952, 7, 15), date(1954, 1, 31)), + ), + prior_disability_periods_provenance=OBSERVED, + current_disability_period_established=True, + current_disability_period_provenance=OBSERVED, + current_disability_period_end=date(1954, 12, 31), + current_disability_period_end_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + month = date(1968, 1, 1) + years = history( + person, + month, + { + 1938: 1, + 1946: 4, + 1947: 4, + 1948: 4, + 1949: 1, + 1951: 4, + 1952: 2, + }, + ) + # The supplied prior has the captured alternate's 20 total QCs and + # all six continuous 1951 Q1--1952 Q2 credits. For the current onset, + # both 0000 and 1111 are invalid; seven middle fillings clear overlap. + flags = [ + flags + for flags in product((False, True), repeat=4) + if not fixed_first or flags[0] + ] + valid = [ + _classification( + person, + {**years, 1954: i.CoverageYear(OBSERVED, qc_quarters=f)}, + month, + ) + for f in flags + ] + assert valid == ( + [False] * 8 if fixed_first else [False] + [True] * 7 + [False] * 8 + ) + years[1954] = i.CoverageYear( + OBSERVED, + agricultural_wages=Fraction(100), + quarterly_wages=(Fraction(50) if fixed_first else Fraction(0),) + + (Fraction(0),) * 3, + ) + if reverse: + years = dict(reversed(tuple(years.items()))) + if any(valid): + row = _evaluate(person, years, month) + assert ( + row.unsupported.reason + is i.InsuredUnsupportedReason.PRE1955_AGRICULTURE + ) + assert count_family_outcomes((row,)).weight == Fraction(3, 2) + else: + _no_row(person, years, month) + + +@pytest.mark.parametrize("year,values,reason", EARLY) +def test_schema_validation_precedes_deferred_qc_refusals(year, values, reason): + person, years, month = _early_case(year, relevant=True) + years[year] = i.CoverageYear(OBSERVED, **values) + years.pop(max(years)) + with pytest.raises(i.InvalidFamilyInput, match="Every coverage year"): + _evaluate(person, years, month) diff --git a/tests/test_track_b_insured_status_fix_round_6_routes.py b/tests/test_track_b_insured_status_fix_round_6_routes.py new file mode 100644 index 000000000..058067083 --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_6_routes.py @@ -0,0 +1,334 @@ +"""Statutory conformance: settled alternate routes and quarter overlaps. + +Invented declarations and captured statutory text only; no population, +behavioral, payment, or forecast claim. +""" + +import calendar +from dataclasses import replace +from datetime import date +from fractions import Fraction +from itertools import product + +import pytest +from hypothesis import given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as i +from populace_dynamics.track_b.gross_benefits import count_family_outcomes +from tests.test_track_b_insured_status import history +from tests.test_track_b_insured_status_fix_round_4_routes import ( + _pre1956_case, +) +from tests.test_track_b_insured_status_sources import source_text + +OBSERVED = i.EarningsProvenance.OBSERVED +UNKNOWN = i.EarningsProvenance.UNKNOWN + + +def _ordinary_pre1956_case(*, unknown_prior=False): + person = i.Person( + date(1920, 2, 2), + disability_onset=date(1955, 1, 15), + current_disability_period_established=True, + current_disability_period_provenance=OBSERVED, + prior_disability_periods_provenance=( + UNKNOWN if unknown_prior else OBSERVED + ), + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + month = date(1968, 1, 1) + years = history(person, month, {year: 4 for year in range(1950, 1955)}) + return person, years, month + + +def _row(person, years, month): + return i.evaluate_insured_status( + "round-six-route", + Fraction(11, 5), + lambda: i.insured_status( + person, years, month, test=i.InsuredTest.FULLY + ), + ) + + +def _assert_invalid_without_row(person, years, month): + rows = [] + with pytest.raises(i.InvalidFamilyInput): + rows.append(_row(person, years, month)) + assert rows == [] + assert count_family_outcomes(rows).rows == 0 + + +def test_pre1956_alternate_exclusion_is_quoted_from_capture(): + assert ( + "does not have 20/40 for freeze or DIB in any quarter before 10/60" + ) in source_text("poms_rs_00301_480") + + +def test_twenty_of_forty_before_october_1960_excludes_alternate_refusal(): + person, years, month = _ordinary_pre1956_case() + result = i.insured_status(person, years, month, test=i.InsuredTest.FULLY) + assert result.fully.insured + assert result.current_disability_period_start == date(1955, 1, 15) + + +def test_twenty_of_forty_scan_includes_later_disabled_quarters_before_1960(): + person, years, month = _ordinary_pre1956_case() + years[1950] = i.CoverageYear(OBSERVED, qc_quarters=(False,) * 4) + years[1940] = i.CoverageYear(OBSERVED, qc_quarters=(True,) * 4) + years[1956] = i.CoverageYear(OBSERVED, qc_quarters=(True,) * 4) + result = i.insured_status(person, years, month, test=i.InsuredTest.FULLY) + assert result.fully.insured + assert result.current_disability_period_start == date(1956, 10, 1) + + +@pytest.mark.parametrize("quarter", [3, 4]) +def test_twenty_of_forty_alternate_exclusion_stops_before_october_1960( + quarter, +): + person, years, month = _ordinary_pre1956_case() + years[1950] = i.CoverageYear(OBSERVED, qc_quarters=(False,) * 4) + years[1940] = i.CoverageYear(OBSERVED, qc_quarters=(True,) * 4) + years[1955] = i.CoverageYear( + OBSERVED, qc_quarters=(True, True, True, False) + ) + years[1960] = i.CoverageYear( + OBSERVED, + qc_quarters=tuple(n == quarter for n in range(1, 5)), + ) + row = _row(person, years, month) + if quarter == 3: + assert row.unsupported is None + assert row.result.fully.insured + assert row.result.current_disability_period_start == date(1960, 7, 1) + else: + assert ( + row.unsupported.reason + is i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956 + ) + + +@pytest.mark.parametrize("route", ["blind", "young"]) +def test_other_ordinary_disability_routes_do_not_supply_twenty_of_forty( + route, +): + person, years, month = _pre1956_case() + if route == "blind": + person = replace(person, statutory_blindness=True) + month = date(1973, 1, 1) + years = {**history(person, month), **years} + else: + person = replace(person, birth_date=date(1930, 2, 2)) + ordinary = replace(person, current_disability_period_established=False) + result = i.insured_status( + ordinary, years, month, test=i.InsuredTest.DISABILITY + ) + assert result.disability.insured + assert result.disability.required == 6 + assert result.disability.rule == ( + "blindness_fully_only" if route == "blind" else "under31_special" + ) + row = _row(person, years, month) + assert ( + row.unsupported.reason + is i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956 + ) + + +@settings(max_examples=12, deadline=None) +@given(extra_year=st.sampled_from([1940, 1949, 1955, 1960])) +def test_fixed_twenty_of_forty_exclusion_survives_extra_unknown_credits( + extra_year, +): + person, years, month = _ordinary_pre1956_case() + years[extra_year] = i.CoverageYear(UNKNOWN) + row = _row(person, years, month) + assert row.unsupported is None + assert row.result.fully.insured + + +def test_some_twenty_of_forty_fillings_keep_named_alternate_refusal(): + person, years, month = _ordinary_pre1956_case() + years[1940] = i.CoverageYear(OBSERVED, qc_quarters=(True,) * 4) + years[1950] = i.CoverageYear(UNKNOWN) + outcomes = [] + for flags in product((False, True), repeat=4): + concrete = {**years, 1950: i.CoverageYear(OBSERVED, qc_quarters=flags)} + row = _row(person, concrete, month) + if all(flags): + assert row.unsupported is None + assert row.result.fully.insured + outcomes.append("ordinary") + else: + assert ( + row.unsupported.reason + is i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956 + ) + outcomes.append("alternate") + assert outcomes.count("ordinary") == 1 + assert outcomes.count("alternate") == 15 + row = _row(person, years, month) + assert ( + row.unsupported.reason + is i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956 + ) + denominator = count_family_outcomes((row,)) + assert denominator.rows == denominator.unsupported_rows == 1 + assert ( + denominator.weight == denominator.unsupported_weight == Fraction(11, 5) + ) + + +def test_excluding_alternate_preserves_ordinary_current_establishment(): + person, years, month = _ordinary_pre1956_case() + credits = { + year: i._credits(year, row, True) for year, row in years.items() + } + assert i._could_establish_current_period( + person, years, credits, month, None, 20 + ) + + +def test_excluding_alternate_preserves_possible_nonempty_prior_history(): + person, years, month = _ordinary_pre1956_case(unknown_prior=True) + credits = { + year: i._credits(year, row, True) for year, row in years.items() + } + # Ordinary 20/40 in 1954 Q4 permits a prior period before 1955 onset. + # Excluding the alternate route cannot prove that history empty. + assert not i._unknown_prior_history_is_empty(person, credits, month, None) + row = _row(person, years, month) + assert count_family_outcomes((row,)).rows == 1 + if row.unsupported is not None: + assert ( + row.unsupported.reason + is i.InsuredUnsupportedReason.UNKNOWN_PERIODS + ) + else: + assert row.result.fully.insured + + +def _immutable_overlap_case(): + person = i.Person( + date(1940, 2, 2), + disability_onset=date(1977, 2, 15), + prior_disability_periods=( + i.DisabilityPeriod(date(1970, 1, 1), date(1977, 1, 31)), + ), + prior_disability_periods_provenance=OBSERVED, + current_disability_period_established=True, + current_disability_period_provenance=OBSERVED, + current_disability_period_end=date(1977, 3, 31), + current_disability_period_end_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + month = date(1978, 1, 1) + years = history(person, month, {1968: 4, 1969: 4}) + years.update({year: i.CoverageYear(UNKNOWN) for year in range(1974, 1978)}) + return person, years, month + + +def test_fixed_same_quarter_overlap_precedes_large_filling_refusal(): + _assert_invalid_without_row(*_immutable_overlap_case()) + + +@settings(max_examples=12, deadline=None) +@given( + ending_month=st.sampled_from([2, 3]), + extra_unknown=st.sampled_from([None, 1973, 1978]), +) +def test_immutable_overlap_is_independent_of_credit_uncertainty( + ending_month, extra_unknown +): + person, years, month = _immutable_overlap_case() + person = replace( + person, + current_disability_period_end=date( + 1977, ending_month, calendar.monthrange(1977, ending_month)[1] + ), + ) + if extra_unknown is not None: + years[extra_unknown] = i.CoverageYear(UNKNOWN) + _assert_invalid_without_row(person, years, month) + + +def test_large_overlap_neighbour_keeps_valid_filling(): + person, years, month = _immutable_overlap_case() + person = replace( + person, + prior_disability_periods=( + i.DisabilityPeriod(date(1970, 1, 1), date(1976, 12, 31)), + ), + ) + row = _row(person, years, month) + assert ( + row.unsupported.reason is i.InsuredUnsupportedReason.UNKNOWN_EARNINGS + ) + concrete = dict(years) + concrete.update( + { + year: i.CoverageYear(OBSERVED, qc_quarters=(True,) * 4) + for year in range(1974, 1978) + } + ) + result = i.insured_status( + person, concrete, month, test=i.InsuredTest.FULLY + ) + assert result.fully.insured + assert result.current_disability_period_start == date(1977, 2, 15) + + +@pytest.mark.parametrize("twentieth_quarter", [2, 3]) +def test_alternate_exclusion_uses_existing_disability_scan_fra_boundary( + twentieth_quarter, +): + person = i.Person( + date(1888, 5, 2), + sex=i.Sex.FEMALE, + disability_onset=date(1952, 7, 15), + current_disability_period_established=True, + current_disability_period_provenance=OBSERVED, + current_disability_period_end=date(1952, 9, 30), + current_disability_period_end_provenance=OBSERVED, + prior_disability_periods_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + month = date(1968, 1, 1) + years = history( + person, + month, + { + 1938: 2, + 1944: 4, + 1945: 4, + 1946: 4, + 1951: 4, + }, + ) + years[1952] = i.CoverageYear( + OBSERVED, qc_quarters=(True, True, False, True) + ) + years[1953] = i.CoverageYear( + OBSERVED, + qc_quarters=tuple(q == twentieth_quarter for q in range(1, 5)), + ) + assert i._fra_date(person) == date(1953, 5, 1) + if twentieth_quarter == 2: + # The ordinary exclusion is available before FRA, but its first + # insured quarter is later than the fixed 1952 ending. + _assert_invalid_without_row(person, years, month) + else: + # A first ordinary witness after FRA cannot displace the valid + # alternate start in July 1952, before the fixed ending. + row = _row(person, years, month) + assert ( + row.unsupported.reason + is i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956 + ) + assert count_family_outcomes((row,)).unsupported_weight == Fraction( + 11, 5 + ) diff --git a/tests/tier_counts.json b/tests/tier_counts.json index a29190794..62848a0d6 100644 --- a/tests/tier_counts.json +++ b/tests/tier_counts.json @@ -1,7 +1,7 @@ { "schema_version": 1, "counts": { - "unit": 20585, + "unit": 20640, "artifact": 4271, "integration_psid": 1471, "reproduction_legacy": 520, From 15a8575f2eaee0f9377fd2b8e74ff649cdc67917 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sat, 31 Oct 2026 13:09:25 -0400 Subject: [PATCH 12/46] Preserve the pre-1956 alternate when 20/40 first appears at FRA (#562 round 7) Sol's sixth review found that the RS 00301.480 A exclusion accepted a witness in a quarter beginning in the FRA month. That quarter can't start a period before its mandatory ending or supply a pre-FRA DIB month, yet it removed the earlier route, and the proof raised an input error. The scan now stops at the quarter containing the last day of the month before FRA, for every person, because a freeze or DIB can't follow FRA whether or not this record shows an established period (Act 216(i)(2)(D); 20 CFR 404.315(a), 404.321(a)-(b)). The lane also found that a successful witness returned before the route's check for people with no established period. A DISABILITY witness at or after FRA now reaches that check. Tests cover all twelve FRA months and an independent date oracle in both directions. The tier files add this round's 24 unit tests to the previous sum; the coordinator's slot recount replaces them. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 68 +++++- .../track_b_insured_status_mutations.json | 135 ++++++++++- .../track_b/insured_status.py | 28 ++- tests/README-tiers.md | 4 +- ...test_track_b_insured_status_fix_round_7.py | 210 ++++++++++++++++++ tests/tier_counts.json | 2 +- 6 files changed, 421 insertions(+), 26 deletions(-) create mode 100644 tests/test_track_b_insured_status_fix_round_7.py diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index fe382485a..8fa152110 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -126,13 +126,18 @@ specialist declarations remain separately preserved. RS .480 A also makes that automatic alternate unavailable if even the lower-credit filling has 20/40 in a disabled quarter before October 1960. The test uses the ordinary disability window, including favorable use or disregard of all prior -periods, from onset through the earlier of the query and 1960Q3, -retaining the existing disability scan's FRA-quarter cap for established -periods (404.321). This exclusion scan precedes the alternate start's -fixed-horizon cap: a later -disabled quarter can exclude the route even if the alternate start itself -would have to precede a supplied administrative end. If some feasible -fillings still lack 20/40, application facts remain absent and the +periods, from onset through the earliest of the query, 1960Q3, and the +quarter containing the last day of the month before FRA. The FRA bound +applies regardless of whether a period is declared established: the +witness must support a freeze or DIB (Act 216(i)(2)(D); 404.315(a); +404.321(a)–(b)). A quarter beginning before the FRA month remains eligible +when FRA falls in its second or third month. This exclusion scan precedes +the alternate start's fixed-horizon cap: a later disabled quarter can +exclude the route even if the alternate start itself would have to precede +a supplied administrative end. Medical onset declares continuous +disability through query; an administrative end does not declare medical +recovery. The interface cannot express current onset followed by recovery. If some +feasible fillings still lack 20/40, application facts remain absent and the alternate possibility retains its refusal. On the ordinary route, a valid filling must supply one insured start that is at or before the declared @@ -587,7 +592,7 @@ to a statutory sentence that does not state it. | I5. A supplied `special_insured` prior period begins before the age-31 attainment quarter. | B404.130(d)(1): a prior period "began before age 31" and the worker "were only insured under paragraph (c)"; (c)(1) requires age 31 not yet attained. A216(i)(3)(B)(iii) expressly uses "before the quarter" of age 31. The flag declares this particular adjudicated young-worker route, not every possible special credit regime. | | I6. An alien worker's actual pre2004 SSN assignment conflicts with declared SSPA applicability; birth on/after January 1, 2004 conflicts with declared exemption. Both never-assigned and an assigned SSN, or assignment before birth, remain invalid. A worker born before 2004 may pair a post2003 assignment or never-assigned status with an adjudicated exemption. | RS .102 B.1 says an alien assigned an SSN before 2004 "is exempt", including a nonwork SSN. B.3.b says, "If an alien worker could have legitimately been assigned an SSN before 1/1/2004, the worker is exempt from the requirements of section 211 of the SSPA." Its wrong-number SS-5 scenario issued another person's number "instead of assigning the alien worker their own SSN". Thus observed or convention-filled exemption overrides either later-assignment or never-assigned presumptions when legitimate pre2004 assignment was possible. Birth on/after January 1, 2004 rules out that exception independently of the assignment record. B.4.b's worker without an SSN "is nevertheless considered to meet the work SSN requirement" when work-authorized; meeting that requirement alone supplies no exemption. | | I7. Explicit quarterly QCs or positive quarterly wages cannot occur before birth, after the query/coverage-end quarter, or after the death quarter. Every required coverage year is declared exactly once through the earliest query, exit, or death year. | A213(a)(2)(B)(i), (v): "no quarter after the quarter in which an individual dies" and "no quarter shall be counted ... prior to the beginning of such quarter"; B404.146(a)-(b) agree. Birth and supplied-record exit caps, complete years, and no implicit zeros are interface premises. Annual counts are capped rather than dated after exit. Specialist earned-basis or additional-credit declarations remain refusals and do not reinterpret an explicit ordinary covered-quarter declaration. | -| I8. A declared current establishment with no possible insured start is invalid only after the shared possibility check excludes every route and every feasible prior/earnings filling. One ordinary filling must satisfy the start, declared end, continuity, and overlap constraints together. | C320(b)(2) requires insured disability "in the calendar quarter in which you became disabled, or in a later calendar quarter"; C321(a) chooses the first such quarter. B404.130(a) says "four different rules"; RS .480 supplies an additional historical test with "at least 20 quarters of coverage" and every qualifying 1951 quarter, subject to its own 20/40 exclusion and the existing disability scan's FRA-quarter cap (C321). Independent flagged and automatic guards preserve available routes; the automatic pre1956 scan obeys the same immutable starting horizon. The ordinary scan is capped by the declared end and continuity date as well as query/death/FRA. Maximum credits decide whether insurance by that fixed date is possible. A failure caused by a derived prior-quarter overlap first checks whether any candidate starting quarter clears the supplied periods, then requires a lower-credit or enumerated filling with a nonoverlapping first start by the same cap. A witness after the declared end never supplies possibility. | +| I8. A declared current establishment with no possible insured start is invalid only after the shared possibility check excludes every route and every feasible prior/earnings filling. One ordinary filling must satisfy the start, declared end, continuity, and overlap constraints together. | C320(b)(2) requires insured disability "in the calendar quarter in which you became disabled, or in a later calendar quarter"; C321(a) chooses the first such quarter. B404.130(a) says "four different rules"; RS .480 supplies an additional historical test with "at least 20 quarters of coverage" and every qualifying 1951 quarter, subject to its own 20/40 exclusion through the quarter containing the last day of the month before FRA, for every person (A216(i)(2)(D), C315(a), C321(a)–(b)). Independent flagged and automatic guards preserve available routes; the automatic pre1956 scan obeys the same immutable starting horizon. The ordinary scan is capped by the declared end and continuity date as well as query/death/FRA. Maximum credits decide whether insurance by that fixed date is possible. A failure caused by a derived prior-quarter overlap first checks whether any candidate starting quarter clears the supplied periods, then requires a lower-credit or enumerated filling with a nonoverlapping first start by the same cap. An ordinary or alternate starting witness after the declared end never supplies possibility; a later pre-FRA 20/40 exclusion witness can still remove the alternate. | | I9. Fewer than six maximum feasible ordinary lifetime QCs proves current establishment impossible only when all specialist possibilities have already been excluded. | B404.110(b)(1): "You need at least 6 QCs but not more than 40 QCs"; B404.130(a): "you must be fully insured". B404.110(a) separately names deemed veteran/nonprofit routes, and RS .131/.350 cover other credits. Those alternatives prevent applying the ordinary six-QC input-error proof to a potentially valid specialist declaration. A record composed entirely of direct final QC declarations (`qc_count` or `qc_quarters`) and UNKNOWN years already fixes or bounds all admissible QCs, including RR credits, so the RR flag cannot add quarters beyond that envelope. This is the direct-credit input contract, not a claim that ordinary RSDI credits always exhaust freeze credits: RS .131 expressly allows credits "not creditable for other" purposes. If earnings allocation or that final-credit declaration is unresolved, the RR route remains possible; RS .230 and .350 supply annual and historical RR credit rules. Period exclusions alone cannot add ordinary QCs. | | I10. The supported calendar, mandatory historical sex, and explicit establishment declaration must be supplied: birth years 1870–9900, query years through 9990, sex for births before January 2, 1913, and establishment provenance whenever onset is present. | These are interface-domain requirements. B404.110(b)(2) and .132 apply different historical male/female endpoints; B404.110(c) excludes only a period "we established for you". Missing facts are not inferred. Calendar limits reserve space for date arithmetic and assert no legal incapacity outside the implementation domain; alternative credit routes cannot supply missing declared facts. | | I11. A continues-through observation requires established disability, cannot precede medical onset or the first feasible insured start, cannot exceed the pre-FRA or death boundary, and cannot follow a declared administrative end. | C320(b)(2) and C321(a) require the insured start; A216(i)(2)(D) and C321(c) bound the period's end. A declaration that a period was in force on a date requires that date to lie within one possible period. This is a dated observation, not an asserted ending; a date later than the query is allowed. Provenance and convention identifiers follow the existing fact schema. | @@ -605,14 +610,14 @@ to a statutory sentence that does not state it. | U7. UNKNOWN SSPA applicability preserves an ordinary QC-only false status, but never a QC-only true status. | RS .102 B.2 says the worker "must meet one of the following additional requirements" and may fail "even if" the QC requirement is met. Applicability can remove ordinary insurance and cannot supply missing QCs. Known applicability retains adjudication refusal; any separate specialist path is refused first. | | U8. With UNKNOWN prior history, a known current period's start is certain onset only if the lower-credit favorable-disregard witness already insures at onset; otherwise the start stays unknown. | A216(i)(2)(C) and C321(a) make insured onset the earliest legal start. C320(a)'s disregard permits that witness, and no route can move this period before medical onset. Other potentially valid histories prevent an impossibility error but do not fabricate a start. | | U9. A continues-through observation removes only candidate administrative ends before its date; it never supplies an ending endpoint or removes UNKNOWN-end disclosure. | C321(c) enumerates actual ending events. Observation of a period still in force supplies a lower bound on those events, not their occurrence. Same-quarter ends remain possible, while a later-quarter observation makes the query quarter interior. | -| U10. An automatic alternate-pre1956 possibility can be removed for every filling only when the lower-credit filling already has ordinary 20/40 in the route's disabled-quarter scan before October 1960. | RS .480 A makes the test available only to a disabled worker who "does not have 20/40 for freeze or DIB in any quarter before 10/60". Ordinary fixed-treatment recent-credit counts are monotone in added credits. The scan uses the ordinary 40-quarter window with favorable all-period use/disregard, from onset through the earlier of query and 1960Q3, retaining the existing FRA-quarter cap for established periods (C321); it does not substitute the young-worker or blindness rule and is not capped by an earlier administrative end. A lower-credit 20/40 witness therefore excludes the alternate for every completion; an upper-only witness cannot do so. Application facts remain absent and are not inferred from this exclusion. The same guard is used for current-establishment and earliest-prior-history possibilities. | +| U10. An automatic alternate-pre1956 possibility can be removed for every filling only when the lower-credit filling already has ordinary 20/40 in the route's disabled-quarter scan before October 1960. | RS .480 A makes the test available only to a disabled worker who "does not have 20/40 for freeze or DIB in any quarter before 10/60". Ordinary fixed-treatment recent-credit counts are monotone in added credits. The scan uses the ordinary 40-quarter window with favorable all-period use/disregard, from onset through the earliest of query, 1960Q3, and the quarter containing the last day of the month before FRA, for every person (A216(i)(2)(D), C315(a), C321(a)–(b)). A quarter stays eligible if FRA falls in its second or third month. It does not substitute the young-worker or blindness rule. The scan ignores an earlier administrative end because `disability_onset` declares continuous medical disability through query, so a later quarter remains a quarter under a disability. The interface cannot express a worker who recovers after current onset; an administrative end must not stand in for recovery. A lower-credit 20/40 witness therefore excludes the alternate for every completion; an upper-only witness cannot do so. Application facts remain absent and are not inferred from this exclusion. The same guard is used for current-establishment and earliest-prior-history possibilities. | | ID and bound | Captured text and alternative-route defense | | --- | --- | | B1. UNKNOWN annual ordinary QCs range from zero through four, reduced by assignable birth/query/death/exit quarters. Deferred raw-conversion rows use their feasible minimum/maximum fillings only for establishment possibility. Exact annual amounts are monotone in earnings; every calendar year stays in 0–4. | B404.143: "we cannot credit you with more than four QCs for any calendar year"; A213(a)(2)(B)(vi) prohibits duplicate calendar-quarter QCs; B404.146 excludes unbegun/death quarters. Birth/exit are supplied-record premises. Additional-credit regimes retain refusal and cannot escape this bound through an ordinary result. Deferred rows still raise their original conversion refusal after a valid possibility survives; no temporary filling is exposed as a computed status. | | B2. Ordinary fully insured requirements lie in 6–40 and exclude only established disability years. Every elapsed-year endpoint uses its relevant candidate year and the historical sex/cohort rule. | B404.110(b)(1), (b)(2), (c), .132; A214(a) says "not counting ... any year any part of which was included in a period of disability". Medical onset without establishment cannot freeze years. Deemed/transitional alternatives are refused before using the ordinary requirement as universal. | | B3. A simplified-pre1951 possibility uses the smallest known freeze requirement, or six for unresolved establishment/history, and maximum post1950 ordinary credits without exclusions. UNKNOWN pre1951 raw wages remain potentially decisive. | A213(c) grants "one quarter of coverage for each $400" subject to resulting fully insured status; B404.110(c)-(d); RS .315 B.1-B.2 record alternate historical/application conditions. This is an over-approximation for refusal, not a computed deemed-credit answer. A favorable ordinary witness with a higher requirement cannot narrow it. | -| B4. An alternate-pre1956 possibility uses maximum feasible QCs and any eligible 1952Q3–1955Q4 quarter with at least 20 total QCs and every preceding 1951-onward quarter credited, minimum six, only if lower credits do not already establish 20/40 in its disabled-quarter scan before October 1960. Current establishment also requires the alternate quarter to fit every fixed starting bound. | RS .480 A requires "at least 20 quarters of coverage" and "all quarters beginning with 03/51 ... are QCs" with "at least six", and limits eligibility to workers without 20/40 before 10/60. B.1 gives first freeze day 07/01/52 and last 12/31/55. The first possible freeze day is July 1, 1952; an established current period already ended, or observed in force, before then cannot use a later automatic witness. The automatic scan shares the ordinary immutable end/continuity/death/FRA horizon. The exclusion retains the existing disability scan's FRA-quarter cap for established periods (C321). A lower-credit ordinary 20/40 witness removes the route for all fillings; an upper-only witness leaves it possible. Unmodeled application restrictions can only remove candidates, so they cannot justify an input error. Explicit specialist flags remain independent possibilities. | +| B4. An alternate-pre1956 possibility uses maximum feasible QCs and any eligible 1952Q3–1955Q4 quarter with at least 20 total QCs and every preceding 1951-onward quarter credited, minimum six, only if lower credits do not already establish 20/40 in its disabled-quarter scan before October 1960. Current establishment also requires the alternate quarter to fit every fixed starting bound. | RS .480 A requires "at least 20 quarters of coverage" and "all quarters beginning with 03/51 ... are QCs" with "at least six", and limits eligibility to workers without 20/40 before 10/60. B.1 gives first freeze day 07/01/52 and last 12/31/55. The first possible freeze day is July 1, 1952; an established current period already ended, or observed in force, before then cannot use a later automatic witness. The automatic scan shares the ordinary immutable end/continuity/death/FRA horizon. The exclusion ends in the quarter containing the last day of the month before FRA for every person, independently of established, absent, or UNKNOWN period status (A216(i)(2)(D), C315(a), C321(a)–(b)). A successful ordinary DISABILITY witness beginning in or after the FRA month cannot bypass an otherwise possible alternate refusal; pre-FRA ordinary witnesses keep their existing results. A lower-credit ordinary 20/40 witness removes the route for all fillings; an upper-only witness leaves it possible. Unmodeled application restrictions can only remove candidates, so they cannot justify an input error. Explicit specialist flags remain independent possibilities. | | B5. Universal recent, fully-prerequisite, and annual count envelopes use zero through maximum feasible ordinary lifetime/year QCs whenever unknown periods/earnings can switch witnesses. | A213(a)(2)(B)(vi) prohibits double credit; B404.146(d) excludes interiors unless disregarded. Every concrete ordinary assignment is a subset of feasible unique lifetime quarters. The envelope permits every witness, even when adding QCs switches to a lower-count witness. Specialist possibilities remain refusals. | | B6. With known earnings and an UNKNOWN ending, returned count bounds include all end-candidate counts admitted by continuity; with entirely known facts they remain exact. | B404.120(b), .130(f), .146(d) distinguish credited endpoints and excluded interiors. All candidate quarters are enumerated, including early endpoints and capped-FRA candidates, subject to any continues-through observation; extrema therefore cover each completion. A continuity date is never inserted as a credited endpoint. No monotonic endpoint-count premise is used. | | B7. DLI lies through query without frozen exit, or through the pre-FRA-quarter/death horizon with frozen coverage; `None` is the bottom bound. A future exit cannot remove query censoring. | RS .148 defines DLI as "the last day in the last quarter" in which status is met and limits the search relative to FRA. B404.146(b) caps credits after death; A216(i)(2)(B) caps new periods. Future undeclared work is not assumed zero. Specialist routes are refused before this ordinary DLI calculation. | @@ -780,11 +785,43 @@ Round 6 adds refusal ordering and settled route exclusions: | --- | --- | | Adding any of the four early raw-conversion refusal facts where it cannot change an all-invalid declaration preserves `InvalidFamilyInput`, zero rows, and zero weight, independently of mapping order. Placing it where concrete credit fillings can validate the declaration preserves the original refusal reason and note. Multiple deferred reasons retain sorted-year priority, including when an overlap search reaches its coverage limit. | `test_irrelevant_early_refusal_fact_preserves_all_invalid_grid_case`; `test_every_early_qc_refusal_preserves_possible_declaration`; `test_deferred_refusals_keep_original_sorted_year_priority`; `test_unresolved_overlap_keeps_original_deferred_refusal` | | An unsupported future increment cannot hide a fixed earlier impossible end, for zero, one, or 10,000 raw wage dollars, including the age-62 and coverage-exit interfaces. The captured increment floor can prove too few possible credits; a sufficient possible filling keeps the original refusal. All schema/history errors still precede deferred refusals. | `test_unrelated_uncaptured_increment_cannot_hide_impossible_fixed_end`; `test_uncaptured_increment_bounds_preserve_both_classifications`; `test_schema_validation_precedes_deferred_qc_refusals` | -| A lower-credit 20/40 witness before October 1960 makes the automatic alternate unavailable under every added unknown-credit filling. The scan includes later disabled quarters and 1960Q3, excludes 1960Q4 and witnesses after the FRA quarter for established periods, and does not substitute blindness or the young-worker rule for 20/40. An upper-only witness preserves the alternate refusal and evaluator row. | `test_fixed_twenty_of_forty_exclusion_survives_extra_unknown_credits`; `test_twenty_of_forty_before_october_1960_excludes_alternate_refusal`; `test_twenty_of_forty_scan_includes_later_disabled_quarters_before_1960`; `test_twenty_of_forty_alternate_exclusion_stops_before_october_1960`; `test_alternate_exclusion_uses_existing_disability_scan_fra_boundary`; `test_other_ordinary_disability_routes_do_not_supply_twenty_of_forty`; `test_some_twenty_of_forty_fillings_keep_named_alternate_refusal` | +| A lower-credit 20/40 witness before October 1960 makes the automatic alternate unavailable under every added unknown-credit filling. The scan includes later disabled quarters and 1960Q3, excludes 1960Q4 and quarters beginning in or after the FRA month for every person, and does not substitute blindness or the young-worker rule for 20/40. An upper-only witness preserves the alternate refusal and evaluator row. | `test_fixed_twenty_of_forty_exclusion_survives_extra_unknown_credits`; `test_twenty_of_forty_before_october_1960_excludes_alternate_refusal`; `test_twenty_of_forty_scan_includes_later_disabled_quarters_before_1960`; `test_twenty_of_forty_alternate_exclusion_stops_before_october_1960`; `test_alternate_exclusion_uses_existing_disability_scan_fra_boundary`; `test_other_ordinary_disability_routes_do_not_supply_twenty_of_forty`; `test_some_twenty_of_forty_fillings_keep_named_alternate_refusal`; `test_independent_date_oracle_classifies_both_alternate_scan_directions` | | Excluding an unavailable alternate does not reject an ordinary current establishment or prove possible nonempty prior history empty. | `test_excluding_alternate_preserves_ordinary_current_establishment`; `test_excluding_alternate_preserves_possible_nonempty_prior_history` | | If every possible starting quarter overlaps a supplied prior quarter, changing credit uncertainty cannot create a valid establishment or a refusal row, even above the filling limit. A neighboring nonoverlapping valid filling remains possible and retains the earnings refusal. | `test_immutable_overlap_is_independent_of_credit_uncertainty`; `test_fixed_same_quarter_overlap_precedes_large_filling_refusal`; `test_large_overlap_neighbour_keeps_valid_filling` | | Deferred historical-credit fillings retain every independently guaranteed quarter. A valid middle filling prevents rejection even when both endpoints are invalid; fixing an overlapping first quarter can instead make every admissible filling invalid. Mapping order changes neither conclusion. | `test_deferred_quarter_fillings_keep_fixed_minimum_and_valid_middle` | +Round 7 pins the eligibility boundary independently of the ordinary scan: + +| Invariant | Executing tests | +| --- | --- | +| A 20/40 witness excludes the alternate exactly when its quarter begins before the FRA month and before October 1960, over all twelve FRA months and witness quarters. Exclusion yields the ordinary result or a genuinely impossible declaration; non-exclusion preserves the named refusal, one evaluator row, and weight 7/3. | `test_independent_date_oracle_classifies_both_alternate_scan_directions` (Hypothesis with an independent date oracle); `test_fra_quarter_stays_only_when_it_begins_before_fra_month` | +| Established, absent, and UNKNOWN current-period declarations share the same FRA exclusion bound. Successful ordinary pre-FRA neighbours retain their results. | `test_unestablished_period_keeps_alternate_after_fra`; `test_unestablished_period_pre_fra_neighbour_keeps_ordinary_result`; `test_reviewed_fra_neighbours_preserve_their_public_results` | +| The reviewed FRA-month witness retains the historical refusal and exact denominator weight under the ordinary query and OP12 exit; a deferred 1937 conversion retains its original reason instead. | `test_fra_month_witness_keeps_reviewed_refusal_and_denominator` | + +The invented boundary example has birth April 2, 1895, female sex, onset +July 15, 1955, and an observed established period ending March 31, 1960. +It has one QC in 1940Q1, all quarters credited in 1951–1954, the first +three credited in 1955, one in 1960Q2, and explicit zeros elsewhere through +1968. It has 20 lifetime QCs and all 18 continuous quarters from 1951Q1 +through 1955Q2 at the alternate 1955Q3 start. Ordinary recent counts are +19 at both 1955Q3 and 1960Q1, then 20 at 1960Q2. FRA is April 1, 1960; +1960Q2 begins too late to supply a freeze or DIB month. The January 1968 +FULLY query therefore preserves `disability_before_1956_unsupported`, one +row, and weight 7/3. The June 1960 OP12 coverage exit gives the same result. +Replacing the zero 1937 row with quarterly wages of $50, $0, $0, $0 keeps +`1937_earnings_allocation_unsupported` with the same row and weight. +The March-birth neighbour also refuses by name; the May-birth neighbour computes fully +insured with ordinary start April 1, 1960. These are invented cases, not +published worked examples. + +No new death cap is needed. History validation rejects explicit credits +after the death quarter; `_world` and `_allowed_quarters` cap every fixed +and flexible assignment there. Prior periods end by death. After the death +quarter each 40-quarter window can only lose earlier credited quarters and +add uncredited quarters, under either all-period treatment. A post-death +20/40 witness therefore implies a death-quarter witness that the scan has +already visited; no first post-death witness can reach the exclusion. + The round-6 ordering example has birth February 2, 2000, onset January 15, 2022, observed establishment ending January 31, 2022, observed exemption and empty prior history, zero QCs through 2027, and raw 2028 wages. At the @@ -1117,7 +1154,14 @@ requirements. Dated observed continuity supplies a missing input; it is not a new statutory reading. They introduce no additional question for Max. Round 6's deferred raw-credit refusals implement the #530 input contract; the alternate-route exclusion and fixed-quarter overlap apply captured -RS .480 A, C320(b)(2), and C321(a). They add no reading for the orchestrator. +RS .480 A, C320(b)(2), and C321(a). Round 7 corrects the FRA bound using +A216(i)(2)(D), C315(a), and C321(a)–(b). Its application to every person +follows RS .480 A's “for freeze or DIB”; establishment is not a condition. +The literal any-quarter scan, contrasted with a scan ending at the declared +administrative end, is recorded as +`us:oasdi-insured-pre1956-alternate-any-quarter-scan`. U10 states its +continuous medical disability premise. The invented side-by-side results +are in the round-7 report for the orchestrator; no payment is computed. Mutation checks are recorded in [`track_b_insured_status_mutations.json`](track_b_insured_status_mutations.json). diff --git a/docs/design/track_b_insured_status_mutations.json b/docs/design/track_b_insured_status_mutations.json index 7eba0e175..01675554f 100644 --- a/docs/design/track_b_insured_status_mutations.json +++ b/docs/design/track_b_insured_status_mutations.json @@ -2302,5 +2302,138 @@ } ], "round_6_note": "Nine isolated in-memory implementation mutations were caught and discarded against the final source. No implementation mutation was written to disk; every child verified the final source SHA-256 stayed unchanged. The original sorted-year conversion refusal, bounded unknown fillings, fixed quarterly minimum, lower-credit 20/40 exclusion with its existing FRA boundary and October 1960 cutoff, and immutable overlap check remain enforced. No existing test assertion was weakened.", - "round_6_final_source_sha256": "223fb5e5b436a12b049d948c9cfdcf9827c606f403ab5ae419a37e2024dc174f" + "round_6_final_source_sha256": "223fb5e5b436a12b049d948c9cfdcf9827c606f403ab5ae419a37e2024dc174f", + "round_7_mutation_control": { + "command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent-trackb-fix-insured-7 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent-trackb-fix-insured-7 PYTHONDONTWRITEBYTECODE=1 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python -m pytest -p no:xdist -p no:cacheprovider -q --tb=short 'tests/test_track_b_insured_status_fix_round_7.py::test_fra_month_witness_keeps_reviewed_refusal_and_denominator[reviewer]' 'tests/test_track_b_insured_status_fix_round_7.py::test_unestablished_period_keeps_alternate_after_fra' 'tests/test_track_b_insured_status_fix_round_7.py::test_fra_quarter_stays_only_when_it_begins_before_fra_month[2]'", + "returncode": 0, + "summary": [ + "6 passed in 5.90s" + ] + }, + "round_7_mutations": [ + { + "name": "alternate_exclusion_uses_fra_attainment_quarter", + "before": "min(_qid(last), 1960 * 4 + 2)", + "after": "min(_qid(month), _fra_quarter(person), 1960 * 4 + 2)", + "pytest_selectors": [ + "tests/test_track_b_insured_status_fix_round_7.py::test_fra_month_witness_keeps_reviewed_refusal_and_denominator[reviewer]" + ], + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_7.py::test_fra_month_witness_keeps_reviewed_refusal_and_denominator[reviewer]" + ], + "summary": [ + "1 failed in 5.32s" + ], + "restored": true, + "method": "Isolated in-memory module mutation; implementation file never changed.", + "environment": { + "PYTHONPATH": "$PWD/src:$PWD", + "OMP_NUM_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent-trackb-fix-insured-7", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent-trackb-fix-insured-7", + "PYTHONDONTWRITEBYTECODE": "1" + }, + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent-trackb-fix-insured-7 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent-trackb-fix-insured-7 PYTHONDONTWRITEBYTECODE=1 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\ndigest = hashlib.sha256(original.encode()).hexdigest()\nprint('source_before_sha256', digest)\nbefore = \"min(_qid(last), 1960 * 4 + 2)\"\nafter = \"min(_qid(month), _fra_quarter(person), 1960 * 4 + 2)\"\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main([\"-p\",\"no:xdist\",\"-p\",\"no:cacheprovider\",\"-q\",\"--tb=short\",\"tests/test_track_b_insured_status_fix_round_7.py::test_fra_month_witness_keeps_reviewed_refusal_and_denominator[reviewer]\"])\nassert Path(i.__file__).read_text() == original\nprint('source_after_sha256', hashlib.sha256(Path(i.__file__).read_bytes()).hexdigest())\nraise SystemExit(result)\nPY", + "source_before_sha256": "fe0d5c32e14d55a85e15890ebb6eb171a2c4e527f17ef7004bab268568001c99", + "source_after_sha256": "fe0d5c32e14d55a85e15890ebb6eb171a2c4e527f17ef7004bab268568001c99" + }, + { + "name": "alternate_exclusion_fra_limit_only_for_established_period", + "before": "last = min(month, _fra_date(person).replace(day=1) - timedelta(days=1))", + "after": "last = min(month, _fra_date(person).replace(day=1) - timedelta(days=1)) if person.current_disability_period_established else month", + "pytest_selectors": [ + "tests/test_track_b_insured_status_fix_round_7.py::test_unestablished_period_keeps_alternate_after_fra" + ], + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_7.py::test_unestablished_period_keeps_alternate_after_fra[2-none]", + "FAILED tests/test_track_b_insured_status_fix_round_7.py::test_unestablished_period_keeps_alternate_after_fra[2-unknown]", + "FAILED tests/test_track_b_insured_status_fix_round_7.py::test_unestablished_period_keeps_alternate_after_fra[3-none]", + "FAILED tests/test_track_b_insured_status_fix_round_7.py::test_unestablished_period_keeps_alternate_after_fra[3-unknown]" + ], + "summary": [ + "4 failed in 6.68s" + ], + "restored": true, + "method": "Isolated in-memory module mutation; implementation file never changed.", + "environment": { + "PYTHONPATH": "$PWD/src:$PWD", + "OMP_NUM_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent-trackb-fix-insured-7", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent-trackb-fix-insured-7", + "PYTHONDONTWRITEBYTECODE": "1" + }, + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent-trackb-fix-insured-7 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent-trackb-fix-insured-7 PYTHONDONTWRITEBYTECODE=1 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\ndigest = hashlib.sha256(original.encode()).hexdigest()\nprint('source_before_sha256', digest)\nbefore = \"last = min(month, _fra_date(person).replace(day=1) - timedelta(days=1))\"\nafter = \"last = min(month, _fra_date(person).replace(day=1) - timedelta(days=1)) if person.current_disability_period_established else month\"\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main([\"-p\",\"no:xdist\",\"-p\",\"no:cacheprovider\",\"-q\",\"--tb=short\",\"tests/test_track_b_insured_status_fix_round_7.py::test_unestablished_period_keeps_alternate_after_fra\"])\nassert Path(i.__file__).read_text() == original\nprint('source_after_sha256', hashlib.sha256(Path(i.__file__).read_bytes()).hexdigest())\nraise SystemExit(result)\nPY", + "source_before_sha256": "fe0d5c32e14d55a85e15890ebb6eb171a2c4e527f17ef7004bab268568001c99", + "source_after_sha256": "fe0d5c32e14d55a85e15890ebb6eb171a2c4e527f17ef7004bab268568001c99" + }, + { + "name": "alternate_exclusion_fra_limit_one_month_early", + "before": "last = min(month, _fra_date(person).replace(day=1) - timedelta(days=1))", + "after": "last = min(month, (_fra_date(person).replace(day=1) - timedelta(days=1)).replace(day=1) - timedelta(days=1))", + "pytest_selectors": [ + "tests/test_track_b_insured_status_fix_round_7.py::test_fra_quarter_stays_only_when_it_begins_before_fra_month[2]" + ], + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_7.py::test_fra_quarter_stays_only_when_it_begins_before_fra_month[2]" + ], + "summary": [ + "1 failed in 5.83s" + ], + "restored": true, + "method": "Isolated in-memory module mutation; implementation file never changed.", + "environment": { + "PYTHONPATH": "$PWD/src:$PWD", + "OMP_NUM_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent-trackb-fix-insured-7", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent-trackb-fix-insured-7", + "PYTHONDONTWRITEBYTECODE": "1" + }, + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent-trackb-fix-insured-7 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent-trackb-fix-insured-7 PYTHONDONTWRITEBYTECODE=1 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\ndigest = hashlib.sha256(original.encode()).hexdigest()\nprint('source_before_sha256', digest)\nbefore = \"last = min(month, _fra_date(person).replace(day=1) - timedelta(days=1))\"\nafter = \"last = min(month, (_fra_date(person).replace(day=1) - timedelta(days=1)).replace(day=1) - timedelta(days=1))\"\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main([\"-p\",\"no:xdist\",\"-p\",\"no:cacheprovider\",\"-q\",\"--tb=short\",\"tests/test_track_b_insured_status_fix_round_7.py::test_fra_quarter_stays_only_when_it_begins_before_fra_month[2]\"])\nassert Path(i.__file__).read_text() == original\nprint('source_after_sha256', hashlib.sha256(Path(i.__file__).read_bytes()).hexdigest())\nraise SystemExit(result)\nPY", + "source_before_sha256": "fe0d5c32e14d55a85e15890ebb6eb171a2c4e527f17ef7004bab268568001c99", + "source_after_sha256": "fe0d5c32e14d55a85e15890ebb6eb171a2c4e527f17ef7004bab268568001c99" + }, + { + "name": "ordinary_success_unconditionally_hides_alternate", + "before": "if lo[0] and (\n kind is not InsuredTest.DISABILITY\n or quarter < _fra_date(person).replace(day=1)\n ):\n return", + "after": "if lo[0]:\n return", + "pytest_selectors": [ + "tests/test_track_b_insured_status_fix_round_7.py::test_unestablished_period_keeps_alternate_after_fra" + ], + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_7.py::test_unestablished_period_keeps_alternate_after_fra[2-none]", + "FAILED tests/test_track_b_insured_status_fix_round_7.py::test_unestablished_period_keeps_alternate_after_fra[2-unknown]", + "FAILED tests/test_track_b_insured_status_fix_round_7.py::test_unestablished_period_keeps_alternate_after_fra[3-none]", + "FAILED tests/test_track_b_insured_status_fix_round_7.py::test_unestablished_period_keeps_alternate_after_fra[3-unknown]" + ], + "summary": [ + "4 failed in 6.93s" + ], + "restored": true, + "method": "Isolated in-memory module mutation; implementation file never changed.", + "environment": { + "PYTHONPATH": "$PWD/src:$PWD", + "OMP_NUM_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent-trackb-fix-insured-7", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent-trackb-fix-insured-7", + "PYTHONDONTWRITEBYTECODE": "1" + }, + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent-trackb-fix-insured-7 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent-trackb-fix-insured-7 PYTHONDONTWRITEBYTECODE=1 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\ndigest = hashlib.sha256(original.encode()).hexdigest()\nprint('source_before_sha256', digest)\nbefore = \"if lo[0] and (\\n kind is not InsuredTest.DISABILITY\\n or quarter < _fra_date(person).replace(day=1)\\n ):\\n return\"\nafter = \"if lo[0]:\\n return\"\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main([\"-p\",\"no:xdist\",\"-p\",\"no:cacheprovider\",\"-q\",\"--tb=short\",\"tests/test_track_b_insured_status_fix_round_7.py::test_unestablished_period_keeps_alternate_after_fra\"])\nassert Path(i.__file__).read_text() == original\nprint('source_after_sha256', hashlib.sha256(Path(i.__file__).read_bytes()).hexdigest())\nraise SystemExit(result)\nPY", + "source_before_sha256": "fe0d5c32e14d55a85e15890ebb6eb171a2c4e527f17ef7004bab268568001c99", + "source_after_sha256": "fe0d5c32e14d55a85e15890ebb6eb171a2c4e527f17ef7004bab268568001c99" + } + ], + "round_7_note": "Four isolated in-memory implementation mutations were caught and discarded against the final source. The FRA-attainment-quarter limit, establishment-only FRA limit, one-month-early limit, and unconditional successful-witness short circuit each fail named public-path tests. Every child verified the disk source SHA-256 stayed unchanged. No implementation mutation was written to disk and no existing test assertion was weakened.", + "round_7_final_source_sha256": "fe0d5c32e14d55a85e15890ebb6eb171a2c4e527f17ef7004bab268568001c99" } diff --git a/src/populace_dynamics/track_b/insured_status.py b/src/populace_dynamics/track_b/insured_status.py index dd066dcb2..42b43d8aa 100644 --- a/src/populace_dynamics/track_b/insured_status.py +++ b/src/populace_dynamics/track_b/insured_status.py @@ -10,6 +10,8 @@ period ends no later than the month before full retirement age; an unknown ending includes every candidate end quarter from insured start through query/cap and permitted continuation. The cap never establishes the end. +The alternate test's 20/40 exclusion uses only quarters beginning before +the FRA month, whether or not a period is declared established. Dated continuity restricts possible endings without establishing an end; a date beyond the query quarter makes that quarter interior to the period. Disability tests @@ -717,7 +719,7 @@ def _coverage_checks(person, years, month, credits): def _observable_coverage_paths( - person, years, month, exit_month, kind, lo, upper, lower + person, years, month, exit_month, kind, lo, quarter, upper, lower ): """Refuse favorable specialist paths revealed by ordinary declarations. @@ -732,7 +734,12 @@ def _observable_coverage_paths( RS 00301.480 likewise reveals a possible pre1956 alternate disability path from onset and earnings; its application facts remain unmodeled. """ - if lo[0]: + # A successful witness at or after FRA cannot resolve an earlier + # alternate route requiring a freeze or DIB month before FRA. + if lo[0] and ( + kind is not InsuredTest.DISABILITY + or quarter < _fra_date(person).replace(day=1) + ): return if kind is InsuredTest.FULLY: before1951 = {year: row for year, row in years.items() if year < 1951} @@ -805,16 +812,14 @@ def _pre1956_alternate_possible( # before October 1960. Only the lower filling can exclude every # completion. Use the ordinary disability window, including favorable # consideration or disregard of all prior periods (404.130(f)). + # A witness must allow a freeze or DIB before FRA (Act 216(i)(2)(D), + # 404.315(a), 404.321(a)-(b)), regardless of declared establishment. + last = min(month, _fra_date(person).replace(day=1) - timedelta(days=1)) lower = credits if lower_credits is None else lower_credits + # Source conflict us:oasdi-insured-pre1956-alternate-any-quarter-scan for quarter in range( - _qid(person.disability_onset), min(_qid(month), 1960 * 4 + 2) + 1 + _qid(person.disability_onset), min(_qid(last), 1960 * 4 + 2) + 1 ): - # Use the established-period disability scan's FRA boundary. - if ( - person.current_disability_period_established - and quarter > _fra_quarter(person) - ): - break for use_periods in ( (True, False) if person.prior_disability_periods else (True,) ): @@ -1586,6 +1591,8 @@ def insured_status( the ending changes a requested status, and is always capped before FRA. Each disability window ends at its tested quarter, from onset through query, and the first insured quarter supplies the witness (404.131). + An alternate for disability before 1956 is excluded only by 20/40 in a + quarter beginning before the FRA month, independently of establishment. Establishment is an input error only if no ordinary, observable, or flagged specialist route could validate any completion of the facts. History validation runs first. Uncomputable QC rows use bounded @@ -1779,7 +1786,7 @@ def insured_status( InsuredUnsupportedReason.CURRENT_PERIOD_END, f"Unobserved statutory period end decides {kind.value}", ) - for p, (witness, _) in zip( + for p, (witness, quarter) in zip( decision_lo_people, lo_candidates, strict=True ): _observable_coverage_paths( @@ -1789,6 +1796,7 @@ def insured_status( coverage_end_month, kind, witness, + quarter, upper, lower, ) diff --git a/tests/README-tiers.md b/tests/README-tiers.md index 61b3ae1e1..b2519a8d9 100644 --- a/tests/README-tiers.md +++ b/tests/README-tiers.md @@ -39,9 +39,9 @@ pytest --collect-only -q -m oracle_policyengine | tail -1 | Tier | Tests at HEAD | |---|---:| -| `unit` | 20,640 | +| `unit` | 20,664 | | `artifact` | 4,271 | | `integration_psid` | 1,471 | | `reproduction_legacy` | 520 | | `oracle_policyengine` | 308 | -| **Total** | **27,210** | +| **Total** | **27,234** | diff --git a/tests/test_track_b_insured_status_fix_round_7.py b/tests/test_track_b_insured_status_fix_round_7.py new file mode 100644 index 000000000..7fcfff994 --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_7.py @@ -0,0 +1,210 @@ +"""Statutory conformance: the alternate scan requires a pre-FRA month. + +Invented declarations only; no population, behavioral, payment, or forecast +claim. Public evaluator rows retain refusals and their exact weights. +""" + +from dataclasses import replace +from datetime import date, timedelta +from fractions import Fraction + +import pytest +from hypothesis import example, given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as i +from populace_dynamics.track_b.gross_benefits import count_family_outcomes +from tests.test_track_b_insured_status import history + +OBSERVED = i.EarningsProvenance.OBSERVED +UNKNOWN = i.EarningsProvenance.UNKNOWN +WEIGHT = Fraction(7, 3) +QUERY = date(1968, 1, 1) + + +def _case(*, fra_year=1960, fra_month=4, witness_year=1960, witness_quarter=2): + # Birth on day two makes FRA day one of the same month, 65 years later. + fra_month_start = date(fra_year, fra_month, 1) + person = i.Person( + date(fra_year - 65, fra_month, 2), + sex=i.Sex.FEMALE, + disability_onset=date(1955, 7, 15), + current_disability_period_established=True, + current_disability_period_provenance=OBSERVED, + current_disability_period_end=fra_month_start - timedelta(days=1), + current_disability_period_end_provenance=OBSERVED, + prior_disability_periods_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + years = history(person, QUERY, {year: 4 for year in range(1951, 1955)}) + years[1940] = i.CoverageYear( + OBSERVED, qc_quarters=(True, False, False, False) + ) + years[1955] = i.CoverageYear( + OBSERVED, qc_quarters=(True, True, True, False) + ) + years[witness_year] = i.CoverageYear( + OBSERVED, + qc_quarters=tuple(q == witness_quarter for q in range(1, 5)), + ) + return person, years + + +def _row(person, years, *, test=i.InsuredTest.FULLY, coverage_end_month=None): + return i.evaluate_insured_status( + "round-seven-fra", + WEIGHT, + lambda: i.insured_status( + person, + years, + QUERY, + test=test, + coverage_end_month=coverage_end_month, + ), + ) + + +def _assert_row(row, reason=None): + denominator = count_family_outcomes((row,)) + assert denominator.rows == 1 + assert denominator.weight == WEIGHT + if reason is None: + assert row.unsupported is None + assert denominator.unsupported_rows == 0 + assert denominator.unsupported_weight == 0 + else: + assert row.unsupported is not None + assert row.unsupported.reason is reason + assert denominator.unsupported_rows == 1 + assert denominator.unsupported_weight == WEIGHT + + +@pytest.mark.parametrize("variant", ["reviewer", "op12", "deferred-1937"]) +def test_fra_month_witness_keeps_reviewed_refusal_and_denominator(variant): + person, years = _case() + coverage_end_month = None + reason = i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956 + if variant == "op12": + coverage_end_month = date(1960, 6, 1) + years = {year: row for year, row in years.items() if year <= 1960} + elif variant == "deferred-1937": + years[1937] = i.CoverageYear( + OBSERVED, + quarterly_wages=(Fraction(50),) + (Fraction(0),) * 3, + ) + reason = i.InsuredUnsupportedReason.EARNINGS_1937 + _assert_row( + _row(person, years, coverage_end_month=coverage_end_month), reason + ) + + +@pytest.mark.parametrize("fra_month", [3, 5]) +def test_reviewed_fra_neighbours_preserve_their_public_results(fra_month): + person, years = _case(fra_month=fra_month) + row = _row(person, years) + if fra_month == 3: + _assert_row(row, i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956) + else: + _assert_row(row) + assert row.result.fully.insured + assert row.result.current_disability_period_start == date(1960, 4, 1) + + +@pytest.mark.parametrize("fra_month", range(1, 13)) +def test_fra_quarter_stays_only_when_it_begins_before_fra_month(fra_month): + # FRA in 1959 exercises October independently of the October 1960 cap. + quarter = (fra_month - 1) // 3 + 1 + person, years = _case( + fra_year=1959, + fra_month=fra_month, + witness_year=1959, + witness_quarter=quarter, + ) + row = _row(person, years) + if fra_month in (1, 4, 7, 10): + _assert_row(row, i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956) + else: + _assert_row(row) + assert row.result.fully.insured + assert row.result.current_disability_period_start == date( + 1959, (quarter - 1) * 3 + 1, 1 + ) + + +def _unestablished(person, state): + return replace( + person, + current_disability_period_established=( + False if state == "none" else None + ), + current_disability_period_provenance=( + OBSERVED if state == "none" else UNKNOWN + ), + current_disability_period_end=None, + current_disability_period_end_provenance=UNKNOWN, + ) + + +@pytest.mark.parametrize("state", ["none", "unknown"]) +@pytest.mark.parametrize("witness_quarter", [2, 3]) +def test_unestablished_period_keeps_alternate_after_fra( + state, witness_quarter +): + person, years = _case(witness_quarter=witness_quarter) + row = _row( + _unestablished(person, state), years, test=i.InsuredTest.DISABILITY + ) + _assert_row(row, i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956) + + +@pytest.mark.parametrize("state", ["none", "unknown"]) +def test_unestablished_period_pre_fra_neighbour_keeps_ordinary_result(state): + person, years = _case(fra_month=5) + row = _row( + _unestablished(person, state), years, test=i.InsuredTest.DISABILITY + ) + _assert_row(row) + assert row.result.disability.insured + assert row.result.disability.qualifying_quarter == date(1960, 4, 1) + + +@settings(max_examples=16, deadline=None) +@example(fra_month=1, witness_year=1960, witness_quarter=1) +@example(fra_month=2, witness_year=1960, witness_quarter=1) +@example(fra_month=3, witness_year=1960, witness_quarter=1) +@example(fra_month=10, witness_year=1960, witness_quarter=4) +@example(fra_month=11, witness_year=1960, witness_quarter=4) +@given( + fra_month=st.integers(1, 12), + witness_year=st.sampled_from([1959, 1960]), + witness_quarter=st.integers(1, 4), +) +def test_independent_date_oracle_classifies_both_alternate_scan_directions( + fra_month, witness_year, witness_quarter +): + # The oracle uses calendar dates alone, not production FRA/quarter helpers. + # The 19 recent QCs become 20 only in the supplied witness quarter. + witness_start = date(witness_year, (witness_quarter - 1) * 3 + 1, 1) + excludes_alternate = witness_start < date( + 1960, fra_month, 1 + ) and witness_start < date(1960, 10, 1) + person, years = _case( + fra_month=fra_month, + witness_year=witness_year, + witness_quarter=witness_quarter, + ) + rows = [] + try: + rows.append(_row(person, years)) + except i.InvalidFamilyInput: + assert excludes_alternate + assert count_family_outcomes(rows).rows == 0 + else: + if excludes_alternate: + _assert_row(rows[0]) + assert rows[0].result.fully.insured + else: + _assert_row( + rows[0], i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956 + ) diff --git a/tests/tier_counts.json b/tests/tier_counts.json index 62848a0d6..167673fa4 100644 --- a/tests/tier_counts.json +++ b/tests/tier_counts.json @@ -1,7 +1,7 @@ { "schema_version": 1, "counts": { - "unit": 20640, + "unit": 20664, "artifact": 4271, "integration_psid": 1471, "reproduction_legacy": 520, From 035f7ba8fbc88e97de48fe4990063366b88e20df Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sat, 31 Oct 2026 13:46:46 -0400 Subject: [PATCH 13/46] Keep pre-1956 alternate refusals past the period's covered quarters (#562 round 8) Round 6's 20/40 scan ignored an earlier declared end, on the note's premise that an administrative end doesn't declare recovery. Sol accepted that reading in its sixth review. The captured 20 CFR 404.321(b) defeats the premise: before December 1980 a period ends at the month before age 65 or two months after the disability ended, so a declared end before FRA in this era means the disability ended. RS 00301.480 A supports two readings. "Any quarter" favors the literal scan; "though under a disability" and "for freeze or DIB" favor a scan limited to the period. A defensible valid reading rules out an input error, so the rule now refuses by name where they differ. It adopts neither reading. For an established period the scan now stops at the declared end, a known continuity date, or onset when neither is known. Every completion's period covers that date. Three round-6 tests pinned the old reading and changed. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 143 +++++++-- .../track_b_insured_status_mutations.json | 182 ++++++++++- .../track_b/insured_status.py | 26 +- tests/README-tiers.md | 4 +- ...ack_b_insured_status_fix_round_6_routes.py | 37 ++- ...test_track_b_insured_status_fix_round_8.py | 283 ++++++++++++++++++ tests/tier_counts.json | 2 +- 7 files changed, 628 insertions(+), 49 deletions(-) create mode 100644 tests/test_track_b_insured_status_fix_round_8.py diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index 8fa152110..b66e29980 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -95,8 +95,10 @@ Periods must not overlap calendar quarters. The ordered period sequence has explicitly means no established periods. The default provenance is `UNKNOWN`, which must contain no periods and never silently means none. -`disability_onset` means medically disabled continuously from that day -through the query month; the rule does not adjudicate recovery. Onset may +`disability_onset` supplies the ordinary continuous-disability premise from +that day through the query month; the rule does not adjudicate recovery. +A declared historical period end can limit the alternate-pre1956 scan, +as required by 404.321(b) below. Onset may be later within the query month, but not in a later month. Onset alone never establishes a period or freezes elapsed years. With an onset, the caller must explicitly declare `current_disability_period_provenance` and @@ -127,18 +129,37 @@ that automatic alternate unavailable if even the lower-credit filling has 20/40 in a disabled quarter before October 1960. The test uses the ordinary disability window, including favorable use or disregard of all prior periods, from onset through the earliest of the query, 1960Q3, and the -quarter containing the last day of the month before FRA. The FRA bound +quarter containing the last day of the month before FRA. For an established +current period it also stops at the declared end, or, with an UNKNOWN end, +the continuity date if supplied and otherwise onset. These are the dates +through which every ending completion still covers the period. The FRA +bound applies regardless of whether a period is declared established: the witness must support a freeze or DIB (Act 216(i)(2)(D); 404.315(a); 404.321(a)–(b)). A quarter beginning before the FRA month remains eligible -when FRA falls in its second or third month. This exclusion scan precedes -the alternate start's fixed-horizon cap: a later disabled quarter can -exclude the route even if the alternate start itself would have to precede -a supplied administrative end. Medical onset declares continuous -disability through query; an administrative end does not declare medical -recovery. The interface cannot express current onset followed by recovery. If some -feasible fillings still lack 20/40, application facts remain absent and the -alternate possibility retains its refusal. +when FRA falls in its second or third month. A witness in the quarter +containing the covered date remains eligible because that quarter begins +on or before it; a witness in the next quarter does not exclude the route. +The captured 404.321(b), headed "When disability ended before December 1, +1980", governs this scan's era and says: + +> Your period of disability ends on the last day of the month before the month in which you become 65 years old or, if earlier, the last day of the second month following the month in which your disability ended. + +An earlier declared end in this era therefore reflects an ended disability; +it cannot be treated as an administrative fact independent of recovery. +Section 404.321(c) supplies different endings when disability ends after +November 1980. This note makes no claim about those endings beyond the +implemented date declarations and candidate evaluation. + +RS .480 A permits two readings. Its "any quarter before 10/60" supports +the literal scan, while "though under a disability" and "for freeze or DIB" +support limiting a witness to the period it could establish. A witness +after a declared end cannot start that period. Where those readings differ, +the rule retains `disability_before_1956_unsupported`; it does not decide +between them. The same protection applies to UNKNOWN endings: an early +ending completion that preserves the route prevents a universal exclusion. +If some feasible fillings still lack 20/40, application facts remain absent +and the alternate possibility retains its refusal. On the ordinary route, a valid filling must supply one insured start that is at or before the declared administrative end and clears every prior-period overlap. A later witness @@ -592,7 +613,7 @@ to a statutory sentence that does not state it. | I5. A supplied `special_insured` prior period begins before the age-31 attainment quarter. | B404.130(d)(1): a prior period "began before age 31" and the worker "were only insured under paragraph (c)"; (c)(1) requires age 31 not yet attained. A216(i)(3)(B)(iii) expressly uses "before the quarter" of age 31. The flag declares this particular adjudicated young-worker route, not every possible special credit regime. | | I6. An alien worker's actual pre2004 SSN assignment conflicts with declared SSPA applicability; birth on/after January 1, 2004 conflicts with declared exemption. Both never-assigned and an assigned SSN, or assignment before birth, remain invalid. A worker born before 2004 may pair a post2003 assignment or never-assigned status with an adjudicated exemption. | RS .102 B.1 says an alien assigned an SSN before 2004 "is exempt", including a nonwork SSN. B.3.b says, "If an alien worker could have legitimately been assigned an SSN before 1/1/2004, the worker is exempt from the requirements of section 211 of the SSPA." Its wrong-number SS-5 scenario issued another person's number "instead of assigning the alien worker their own SSN". Thus observed or convention-filled exemption overrides either later-assignment or never-assigned presumptions when legitimate pre2004 assignment was possible. Birth on/after January 1, 2004 rules out that exception independently of the assignment record. B.4.b's worker without an SSN "is nevertheless considered to meet the work SSN requirement" when work-authorized; meeting that requirement alone supplies no exemption. | | I7. Explicit quarterly QCs or positive quarterly wages cannot occur before birth, after the query/coverage-end quarter, or after the death quarter. Every required coverage year is declared exactly once through the earliest query, exit, or death year. | A213(a)(2)(B)(i), (v): "no quarter after the quarter in which an individual dies" and "no quarter shall be counted ... prior to the beginning of such quarter"; B404.146(a)-(b) agree. Birth and supplied-record exit caps, complete years, and no implicit zeros are interface premises. Annual counts are capped rather than dated after exit. Specialist earned-basis or additional-credit declarations remain refusals and do not reinterpret an explicit ordinary covered-quarter declaration. | -| I8. A declared current establishment with no possible insured start is invalid only after the shared possibility check excludes every route and every feasible prior/earnings filling. One ordinary filling must satisfy the start, declared end, continuity, and overlap constraints together. | C320(b)(2) requires insured disability "in the calendar quarter in which you became disabled, or in a later calendar quarter"; C321(a) chooses the first such quarter. B404.130(a) says "four different rules"; RS .480 supplies an additional historical test with "at least 20 quarters of coverage" and every qualifying 1951 quarter, subject to its own 20/40 exclusion through the quarter containing the last day of the month before FRA, for every person (A216(i)(2)(D), C315(a), C321(a)–(b)). Independent flagged and automatic guards preserve available routes; the automatic pre1956 scan obeys the same immutable starting horizon. The ordinary scan is capped by the declared end and continuity date as well as query/death/FRA. Maximum credits decide whether insurance by that fixed date is possible. A failure caused by a derived prior-quarter overlap first checks whether any candidate starting quarter clears the supplied periods, then requires a lower-credit or enumerated filling with a nonoverlapping first start by the same cap. An ordinary or alternate starting witness after the declared end never supplies possibility; a later pre-FRA 20/40 exclusion witness can still remove the alternate. | +| I8. A declared current establishment with no possible insured start is invalid only after the shared possibility check excludes every route and every feasible prior/earnings filling. One ordinary filling must satisfy the start, declared end, continuity, and overlap constraints together. | C320(b)(2) requires insured disability "in the calendar quarter in which you became disabled, or in a later calendar quarter"; C321(a) chooses the first such quarter. B404.130(a) says "four different rules"; RS .480 supplies an additional historical test with "at least 20 quarters of coverage" and every qualifying 1951 quarter, subject to its own 20/40 exclusion through the quarter containing the last day of the month before FRA, for every person (A216(i)(2)(D), C315(a), C321(a)–(b)). Independent flagged and automatic guards preserve available routes; the automatic pre1956 scan obeys the same immutable starting horizon. The ordinary scan is capped by the declared end and continuity date as well as query/death/FRA. Maximum credits decide whether insurance by that fixed date is possible. A failure caused by a derived prior-quarter overlap first checks whether any candidate starting quarter clears the supplied periods, then requires a lower-credit or enumerated filling with a nonoverlapping first start by the same cap. An ordinary or alternate starting witness after the declared end never supplies possibility. Nor can a later 20/40 witness establish impossibility on every reading of RS .480 A: C321(b) makes the earlier pre-FRA ending evidence that disability ended in this era. The named alternate refusal preserves that defensible route. For an UNKNOWN end, only a witness through the continuity date, or onset when continuity is absent, is shared by every ending completion. | | I9. Fewer than six maximum feasible ordinary lifetime QCs proves current establishment impossible only when all specialist possibilities have already been excluded. | B404.110(b)(1): "You need at least 6 QCs but not more than 40 QCs"; B404.130(a): "you must be fully insured". B404.110(a) separately names deemed veteran/nonprofit routes, and RS .131/.350 cover other credits. Those alternatives prevent applying the ordinary six-QC input-error proof to a potentially valid specialist declaration. A record composed entirely of direct final QC declarations (`qc_count` or `qc_quarters`) and UNKNOWN years already fixes or bounds all admissible QCs, including RR credits, so the RR flag cannot add quarters beyond that envelope. This is the direct-credit input contract, not a claim that ordinary RSDI credits always exhaust freeze credits: RS .131 expressly allows credits "not creditable for other" purposes. If earnings allocation or that final-credit declaration is unresolved, the RR route remains possible; RS .230 and .350 supply annual and historical RR credit rules. Period exclusions alone cannot add ordinary QCs. | | I10. The supported calendar, mandatory historical sex, and explicit establishment declaration must be supplied: birth years 1870–9900, query years through 9990, sex for births before January 2, 1913, and establishment provenance whenever onset is present. | These are interface-domain requirements. B404.110(b)(2) and .132 apply different historical male/female endpoints; B404.110(c) excludes only a period "we established for you". Missing facts are not inferred. Calendar limits reserve space for date arithmetic and assert no legal incapacity outside the implementation domain; alternative credit routes cannot supply missing declared facts. | | I11. A continues-through observation requires established disability, cannot precede medical onset or the first feasible insured start, cannot exceed the pre-FRA or death boundary, and cannot follow a declared administrative end. | C320(b)(2) and C321(a) require the insured start; A216(i)(2)(D) and C321(c) bound the period's end. A declaration that a period was in force on a date requires that date to lie within one possible period. This is a dated observation, not an asserted ending; a date later than the query is allowed. Provenance and convention identifiers follow the existing fact schema. | @@ -610,14 +631,14 @@ to a statutory sentence that does not state it. | U7. UNKNOWN SSPA applicability preserves an ordinary QC-only false status, but never a QC-only true status. | RS .102 B.2 says the worker "must meet one of the following additional requirements" and may fail "even if" the QC requirement is met. Applicability can remove ordinary insurance and cannot supply missing QCs. Known applicability retains adjudication refusal; any separate specialist path is refused first. | | U8. With UNKNOWN prior history, a known current period's start is certain onset only if the lower-credit favorable-disregard witness already insures at onset; otherwise the start stays unknown. | A216(i)(2)(C) and C321(a) make insured onset the earliest legal start. C320(a)'s disregard permits that witness, and no route can move this period before medical onset. Other potentially valid histories prevent an impossibility error but do not fabricate a start. | | U9. A continues-through observation removes only candidate administrative ends before its date; it never supplies an ending endpoint or removes UNKNOWN-end disclosure. | C321(c) enumerates actual ending events. Observation of a period still in force supplies a lower bound on those events, not their occurrence. Same-quarter ends remain possible, while a later-quarter observation makes the query quarter interior. | -| U10. An automatic alternate-pre1956 possibility can be removed for every filling only when the lower-credit filling already has ordinary 20/40 in the route's disabled-quarter scan before October 1960. | RS .480 A makes the test available only to a disabled worker who "does not have 20/40 for freeze or DIB in any quarter before 10/60". Ordinary fixed-treatment recent-credit counts are monotone in added credits. The scan uses the ordinary 40-quarter window with favorable all-period use/disregard, from onset through the earliest of query, 1960Q3, and the quarter containing the last day of the month before FRA, for every person (A216(i)(2)(D), C315(a), C321(a)–(b)). A quarter stays eligible if FRA falls in its second or third month. It does not substitute the young-worker or blindness rule. The scan ignores an earlier administrative end because `disability_onset` declares continuous medical disability through query, so a later quarter remains a quarter under a disability. The interface cannot express a worker who recovers after current onset; an administrative end must not stand in for recovery. A lower-credit 20/40 witness therefore excludes the alternate for every completion; an upper-only witness cannot do so. Application facts remain absent and are not inferred from this exclusion. The same guard is used for current-establishment and earliest-prior-history possibilities. | +| U10. An automatic alternate-pre1956 possibility can be removed for every filling only when the lower-credit filling already has ordinary 20/40 in a quarter covered by every ending completion, before October 1960. | RS .480 A makes the test available only to a disabled worker who "does not have 20/40 for freeze or DIB in any quarter before 10/60". Ordinary fixed-treatment recent-credit counts are monotone in added credits. The scan uses the ordinary 40-quarter window with favorable all-period use/disregard, from onset through the earliest of query, 1960Q3, and the quarter containing the last day of the month before FRA, for every person (A216(i)(2)(D), C315(a), C321(a)–(b)). A quarter stays eligible if FRA falls in its second or third month. It does not substitute the young-worker or blindness rule. For established current periods it additionally ends at the declared end, or the continuity date when the end is UNKNOWN, or onset when both are UNKNOWN. C321(b) governs pre-December-1980 endings; its earlier ending is tied to ended disability rather than an independent administrative event. RS .480 A's "any quarter" supports a literal wider scan, but "though under a disability" and "for freeze or DIB" support excluding post-period witnesses. Where they differ, retain the named alternate refusal. Only a lower-credit 20/40 witness shared by every period-ending completion excludes the alternate for every completion; an upper-only witness cannot do so. Application facts remain absent and are not inferred from this exclusion. The same guard is used for current-establishment and earliest-prior-history possibilities. | | ID and bound | Captured text and alternative-route defense | | --- | --- | | B1. UNKNOWN annual ordinary QCs range from zero through four, reduced by assignable birth/query/death/exit quarters. Deferred raw-conversion rows use their feasible minimum/maximum fillings only for establishment possibility. Exact annual amounts are monotone in earnings; every calendar year stays in 0–4. | B404.143: "we cannot credit you with more than four QCs for any calendar year"; A213(a)(2)(B)(vi) prohibits duplicate calendar-quarter QCs; B404.146 excludes unbegun/death quarters. Birth/exit are supplied-record premises. Additional-credit regimes retain refusal and cannot escape this bound through an ordinary result. Deferred rows still raise their original conversion refusal after a valid possibility survives; no temporary filling is exposed as a computed status. | | B2. Ordinary fully insured requirements lie in 6–40 and exclude only established disability years. Every elapsed-year endpoint uses its relevant candidate year and the historical sex/cohort rule. | B404.110(b)(1), (b)(2), (c), .132; A214(a) says "not counting ... any year any part of which was included in a period of disability". Medical onset without establishment cannot freeze years. Deemed/transitional alternatives are refused before using the ordinary requirement as universal. | | B3. A simplified-pre1951 possibility uses the smallest known freeze requirement, or six for unresolved establishment/history, and maximum post1950 ordinary credits without exclusions. UNKNOWN pre1951 raw wages remain potentially decisive. | A213(c) grants "one quarter of coverage for each $400" subject to resulting fully insured status; B404.110(c)-(d); RS .315 B.1-B.2 record alternate historical/application conditions. This is an over-approximation for refusal, not a computed deemed-credit answer. A favorable ordinary witness with a higher requirement cannot narrow it. | -| B4. An alternate-pre1956 possibility uses maximum feasible QCs and any eligible 1952Q3–1955Q4 quarter with at least 20 total QCs and every preceding 1951-onward quarter credited, minimum six, only if lower credits do not already establish 20/40 in its disabled-quarter scan before October 1960. Current establishment also requires the alternate quarter to fit every fixed starting bound. | RS .480 A requires "at least 20 quarters of coverage" and "all quarters beginning with 03/51 ... are QCs" with "at least six", and limits eligibility to workers without 20/40 before 10/60. B.1 gives first freeze day 07/01/52 and last 12/31/55. The first possible freeze day is July 1, 1952; an established current period already ended, or observed in force, before then cannot use a later automatic witness. The automatic scan shares the ordinary immutable end/continuity/death/FRA horizon. The exclusion ends in the quarter containing the last day of the month before FRA for every person, independently of established, absent, or UNKNOWN period status (A216(i)(2)(D), C315(a), C321(a)–(b)). A successful ordinary DISABILITY witness beginning in or after the FRA month cannot bypass an otherwise possible alternate refusal; pre-FRA ordinary witnesses keep their existing results. A lower-credit ordinary 20/40 witness removes the route for all fillings; an upper-only witness leaves it possible. Unmodeled application restrictions can only remove candidates, so they cannot justify an input error. Explicit specialist flags remain independent possibilities. | +| B4. An alternate-pre1956 possibility uses maximum feasible QCs and any eligible 1952Q3–1955Q4 quarter with at least 20 total QCs and every preceding 1951-onward quarter credited, minimum six, only if lower credits do not already establish 20/40 in its disabled-quarter scan before October 1960. Current establishment also requires the alternate quarter to fit every fixed starting bound. | RS .480 A requires "at least 20 quarters of coverage" and "all quarters beginning with 03/51 ... are QCs" with "at least six", and limits eligibility to workers without 20/40 before 10/60. B.1 gives first freeze day 07/01/52 and last 12/31/55. The first possible freeze day is July 1, 1952; an established current period already ended, or observed in force, before then cannot use a later automatic witness. The automatic scan shares the ordinary immutable end/continuity/death/FRA horizon. The exclusion ends no later than the quarter containing the last day of the month before FRA for every person, independently of established, absent, or UNKNOWN period status (A216(i)(2)(D), C315(a), C321(a)–(b)). An established current period further limits exclusion to the quarter containing the declared end; an UNKNOWN end limits it to the continuity date's quarter, or onset's quarter without continuity. These bounds preserve a named refusal when the literal any-quarter reading and the period-limited reading differ, and ensure that an UNKNOWN result holds for every declared-end completion. A successful ordinary DISABILITY witness beginning in or after the FRA month cannot bypass an otherwise possible alternate refusal. Pre-FRA ordinary witnesses retain their results when the applicable period-covered bound also permits exclusion. A lower-credit ordinary 20/40 witness removes the route for all fillings; an upper-only witness leaves it possible. Unmodeled application restrictions can only remove candidates, so they cannot justify an input error. Explicit specialist flags remain independent possibilities. | | B5. Universal recent, fully-prerequisite, and annual count envelopes use zero through maximum feasible ordinary lifetime/year QCs whenever unknown periods/earnings can switch witnesses. | A213(a)(2)(B)(vi) prohibits double credit; B404.146(d) excludes interiors unless disregarded. Every concrete ordinary assignment is a subset of feasible unique lifetime quarters. The envelope permits every witness, even when adding QCs switches to a lower-count witness. Specialist possibilities remain refusals. | | B6. With known earnings and an UNKNOWN ending, returned count bounds include all end-candidate counts admitted by continuity; with entirely known facts they remain exact. | B404.120(b), .130(f), .146(d) distinguish credited endpoints and excluded interiors. All candidate quarters are enumerated, including early endpoints and capped-FRA candidates, subject to any continues-through observation; extrema therefore cover each completion. A continuity date is never inserted as a credited endpoint. No monotonic endpoint-count premise is used. | | B7. DLI lies through query without frozen exit, or through the pre-FRA-quarter/death horizon with frozen coverage; `None` is the bottom bound. A future exit cannot remove query censoring. | RS .148 defines DLI as "the last day in the last quarter" in which status is met and limits the search relative to FRA. B404.146(b) caps credits after death; A216(i)(2)(B) caps new periods. Future undeclared work is not assumed zero. Specialist routes are refused before this ordinary DLI calculation. | @@ -785,7 +806,7 @@ Round 6 adds refusal ordering and settled route exclusions: | --- | --- | | Adding any of the four early raw-conversion refusal facts where it cannot change an all-invalid declaration preserves `InvalidFamilyInput`, zero rows, and zero weight, independently of mapping order. Placing it where concrete credit fillings can validate the declaration preserves the original refusal reason and note. Multiple deferred reasons retain sorted-year priority, including when an overlap search reaches its coverage limit. | `test_irrelevant_early_refusal_fact_preserves_all_invalid_grid_case`; `test_every_early_qc_refusal_preserves_possible_declaration`; `test_deferred_refusals_keep_original_sorted_year_priority`; `test_unresolved_overlap_keeps_original_deferred_refusal` | | An unsupported future increment cannot hide a fixed earlier impossible end, for zero, one, or 10,000 raw wage dollars, including the age-62 and coverage-exit interfaces. The captured increment floor can prove too few possible credits; a sufficient possible filling keeps the original refusal. All schema/history errors still precede deferred refusals. | `test_unrelated_uncaptured_increment_cannot_hide_impossible_fixed_end`; `test_uncaptured_increment_bounds_preserve_both_classifications`; `test_schema_validation_precedes_deferred_qc_refusals` | -| A lower-credit 20/40 witness before October 1960 makes the automatic alternate unavailable under every added unknown-credit filling. The scan includes later disabled quarters and 1960Q3, excludes 1960Q4 and quarters beginning in or after the FRA month for every person, and does not substitute blindness or the young-worker rule for 20/40. An upper-only witness preserves the alternate refusal and evaluator row. | `test_fixed_twenty_of_forty_exclusion_survives_extra_unknown_credits`; `test_twenty_of_forty_before_october_1960_excludes_alternate_refusal`; `test_twenty_of_forty_scan_includes_later_disabled_quarters_before_1960`; `test_twenty_of_forty_alternate_exclusion_stops_before_october_1960`; `test_alternate_exclusion_uses_existing_disability_scan_fra_boundary`; `test_other_ordinary_disability_routes_do_not_supply_twenty_of_forty`; `test_some_twenty_of_forty_fillings_keep_named_alternate_refusal`; `test_independent_date_oracle_classifies_both_alternate_scan_directions` | +| A lower-credit 20/40 witness in a quarter covered by every ending completion, before October 1960, makes the automatic alternate unavailable under every added unknown-credit filling. The scan includes later disabled quarters and 1960Q3 only when covered by every ending completion, excludes 1960Q4 and quarters beginning in or after the FRA month for every person, and does not substitute blindness or the young-worker rule for 20/40. A declared end includes its own quarter; an UNKNOWN end permits exclusion only through the continuity date or, without continuity, onset. An upper-only witness preserves the alternate refusal and evaluator row. | `test_fixed_twenty_of_forty_exclusion_survives_extra_unknown_credits`; `test_twenty_of_forty_before_october_1960_excludes_alternate_refusal`; `test_twenty_of_forty_scan_includes_later_disabled_quarters_before_1960`; `test_twenty_of_forty_alternate_exclusion_stops_before_october_1960`; `test_alternate_exclusion_uses_existing_disability_scan_fra_boundary`; `test_other_ordinary_disability_routes_do_not_supply_twenty_of_forty`; `test_some_twenty_of_forty_fillings_keep_named_alternate_refusal`; `test_independent_date_oracle_classifies_both_alternate_scan_directions` | | Excluding an unavailable alternate does not reject an ordinary current establishment or prove possible nonempty prior history empty. | `test_excluding_alternate_preserves_ordinary_current_establishment`; `test_excluding_alternate_preserves_possible_nonempty_prior_history` | | If every possible starting quarter overlaps a supplied prior quarter, changing credit uncertainty cannot create a valid establishment or a refusal row, even above the filling limit. A neighboring nonoverlapping valid filling remains possible and retains the earnings refusal. | `test_immutable_overlap_is_independent_of_credit_uncertainty`; `test_fixed_same_quarter_overlap_precedes_large_filling_refusal`; `test_large_overlap_neighbour_keeps_valid_filling` | | Deferred historical-credit fillings retain every independently guaranteed quarter. A valid middle filling prevents rejection even when both endpoints are invalid; fixing an overlapping first quarter can instead make every admissible filling invalid. Mapping order changes neither conclusion. | `test_deferred_quarter_fillings_keep_fixed_minimum_and_valid_middle` | @@ -794,10 +815,30 @@ Round 7 pins the eligibility boundary independently of the ordinary scan: | Invariant | Executing tests | | --- | --- | -| A 20/40 witness excludes the alternate exactly when its quarter begins before the FRA month and before October 1960, over all twelve FRA months and witness quarters. Exclusion yields the ordinary result or a genuinely impossible declaration; non-exclusion preserves the named refusal, one evaluator row, and weight 7/3. | `test_independent_date_oracle_classifies_both_alternate_scan_directions` (Hypothesis with an independent date oracle); `test_fra_quarter_stays_only_when_it_begins_before_fra_month` | +| For the round-7 cases, whose declared ends are the month before FRA, a 20/40 witness excludes the alternate exactly when its quarter begins before the FRA month and before October 1960, over all twelve FRA months and witness quarters. An earlier period-covered bound can further restrict exclusion, as pinned in round 8. Exclusion yields the ordinary result or a genuinely impossible declaration; non-exclusion preserves the named refusal, one evaluator row, and weight 7/3. | `test_independent_date_oracle_classifies_both_alternate_scan_directions` (Hypothesis with an independent date oracle); `test_fra_quarter_stays_only_when_it_begins_before_fra_month` | | Established, absent, and UNKNOWN current-period declarations share the same FRA exclusion bound. Successful ordinary pre-FRA neighbours retain their results. | `test_unestablished_period_keeps_alternate_after_fra`; `test_unestablished_period_pre_fra_neighbour_keeps_ordinary_result`; `test_reviewed_fra_neighbours_preserve_their_public_results` | | The reviewed FRA-month witness retains the historical refusal and exact denominator weight under the ordinary query and OP12 exit; a deferred 1937 conversion retains its original reason instead. | `test_fra_month_witness_keeps_reviewed_refusal_and_denominator` | +Round 8 limits exclusion to quarters covered by every ending completion: + +| Invariant | Executing tests | +| --- | --- | +| A lower-credit 20/40 witness excludes the alternate exactly when its quarter begins on or before the established period's covered date, before the FRA month, and before October 1960. The covered date is the declared end, the continuity date for an UNKNOWN end, or onset when neither is supplied. The ending quarter remains eligible even when the end is in its middle month; the next quarter does not exclude. Both computed and refused outcomes retain one evaluator row and exact weight 11/5. | `test_declared_end_quarter_includes_witness_but_next_quarter_refuses`; `test_unknown_end_keeps_onset_witness_but_refuses_later_quarter`; `test_continuity_quarter_includes_witness_but_later_quarter_refuses`; `test_later_disabled_quarters_with_unknown_end_keep_named_refusal`; `test_october_1960_boundary_with_unknown_end_keeps_named_refusal`; `test_independent_date_oracle_classifies_covered_quarters_both_directions` (Hypothesis with an independent date oracle) | +| If any declared-end completion preserves the named alternate refusal, an UNKNOWN ending returns no status. An onset-quarter witness remains shared by every completion; a witness in a later quarter without continuity does not. | `test_unknown_end_cannot_return_status_when_declared_completion_refuses` (Hypothesis); `test_unknown_end_keeps_onset_witness_but_refuses_later_quarter` | +| The round-7 comparison's ordinary witness after the declared end preserves `disability_before_1956_unsupported`, one evaluator row, and exact weight 11/5. It cannot prove invalidity under every defensible reading. | `test_round_seven_declared_end_comparison_retains_named_refusal`; `test_alternate_exclusion_uses_existing_disability_scan_fra_boundary` | + +The UNKNOWN-end completion invariant does not establish the corresponding +claim for UNKNOWN establishment. The round-7 pre-FRA neighbour born May 2, +1895, with onset July 15, 1955 and first 20/40 in 1960Q2 still computes +ordinary disability insurance when establishment is UNKNOWN. Its +established completion with an early September 30, 1955 end instead +retains the alternate refusal. The successful ordinary short circuit in +`_observable_coverage_paths` precedes that prospective established-period +check. `test_unestablished_period_pre_fra_neighbour_keeps_ordinary_result` +pins the unchanged UNKNOWN-establishment result; the round-8 report records +this separate discrepancy and its conflict with the instruction to preserve +that existing expectation. + The invented boundary example has birth April 2, 1895, female sex, onset July 15, 1955, and an observed established period ending March 31, 1960. It has one QC in 1940Q1, all quarters credited in 1951–1954, the first @@ -810,9 +851,37 @@ FULLY query therefore preserves `disability_before_1956_unsupported`, one row, and weight 7/3. The June 1960 OP12 coverage exit gives the same result. Replacing the zero 1937 row with quarterly wages of $50, $0, $0, $0 keeps `1937_earnings_allocation_unsupported` with the same row and weight. -The March-birth neighbour also refuses by name; the May-birth neighbour computes fully -insured with ordinary start April 1, 1960. These are invented cases, not -published worked examples. +Each birth-month neighbour retains a declared end in the month before its +own FRA: February 29, 1960 for the March birth and April 30, 1960 for the +May birth. The March neighbour also refuses by name; the May neighbour +computes fully insured with ordinary start April 1, 1960. These are invented +cases, not published worked examples. + +The round-7 comparison case has birth May 2, 1888, female sex, onset July +15, 1952, observed establishment ending September 30, 1952, and observed +empty prior history. Credits are two in 1938, four in each of 1944–1946, +four in 1951, 1952Q1, Q2, and Q4, and 1953Q2, with explicit zeros elsewhere +through the January 1968 FULLY query. At onset it has the alternate route's +20 lifetime QCs and all six 1951Q1–1952Q2 QCs. Its first ordinary 20/40 +witness is April 1, 1953, before the May 1 FRA month but after the declared +ending quarter. The literal any-quarter reading removes the alternate and +raises `InvalidFamilyInput` with zero rows; the period-limited reading +preserves the declaration. The pinned result is therefore +`disability_before_1956_unsupported`, one row, and weight 11/5. Moving the +twentieth recent credit to 1953Q3 also refuses, independently of the FRA +bound. These are invented comparisons, not published worked examples. + +The round-8 ending-quarter examples use birth May 2, 1895, onset July 15, +1955, and 19 ordinary recent QCs before a single later witness credit. +With a May 31 or June 30, 1956 declared end, an April 1, 1956 witness +excludes the alternate and computes the ordinary start; a July 1 witness +instead retains the named refusal. With an UNKNOWN end and a May 15, +1956 continuity observation, the April witness excludes and the July +witness refuses. Each outcome retains one row of weight 11/5. The +control born February 2, 1920 remains computed with a January 15, 1955 +onset-quarter witness even when the end is UNKNOWN; moving its first +ordinary witness one quarter later without continuity retains the +alternate refusal. No new death cap is needed. History validation rejects explicit credits after the death quarter; `_world` and `_allowed_quarters` cap every fixed @@ -842,8 +911,14 @@ For the settled historical route, birth February 2, 1920, onset January at onset. All other 1937–1968 quarters are explicitly uncredited. The January 1968 FULLY result is insured, with current start January 15, 1955; RS .480 A excludes its alternate and application facts need not be guessed. -Moving the four 1950 credits to 1940 and supplying four in 1956 instead -gives an ordinary October 1, 1956 start, still within the exclusion scan. +Moving the four 1950 credits to 1940 and supplying four in 1956 instead, +with a declared December 31, 1956 end after the witness, gives an ordinary +October 1, 1956 start within the exclusion scan. Leaving that end UNKNOWN +and supplying no continuity instead preserves +`disability_before_1956_unsupported`, one row, and weight 11/5: an ending +in the onset quarter remains possible. A 1960Q3 witness likewise excludes +with a declared end after it, while its UNKNOWN-end twin refuses; 1960Q4 +still cannot exclude under either ending declaration. With 1950 UNKNOWN and the extra four 1940 credits, enumeration finds one ordinary filling and fifteen alternate-refused fillings; the UNKNOWN declaration preserves `disability_before_1956_unsupported` and weight 11/5. @@ -1157,11 +1232,27 @@ the alternate-route exclusion and fixed-quarter overlap apply captured RS .480 A, C320(b)(2), and C321(a). Round 7 corrects the FRA bound using A216(i)(2)(D), C315(a), and C321(a)–(b). Its application to every person follows RS .480 A's “for freeze or DIB”; establishment is not a condition. -The literal any-quarter scan, contrasted with a scan ending at the declared -administrative end, is recorded as -`us:oasdi-insured-pre1956-alternate-any-quarter-scan`. U10 states its -continuous medical disability premise. The invented side-by-side results -are in the round-7 report for the orchestrator; no payment is computed. +The source conflict remains +`us:oasdi-insured-pre1956-alternate-any-quarter-scan`. RS .480 A says a +worker "though under a disability, does not have 20/40 for freeze or DIB in +any quarter before 10/60". "Any quarter" supports the literal scan; +"though under a disability" and "for freeze or DIB" support the narrower +scan through the declared period. C321(b), quoted above, governs these +pre-December-1980 endings and links an earlier ending to ended disability. +The former premise that an administrative end supplies no recovery evidence +was therefore wrong for this era. C321(c) can differ for post-November-1980 +endings; no wider claim about those endings is made here. + +The implementation keeps the named alternate refusal wherever those +readings differ. A classification as `InvalidFamilyInput` requires every +concrete filling to be invalid on every route, so a defensible reading that +preserves the declaration prevents that input error. An UNKNOWN end needs +the same restraint: a later witness cannot exclude a route preserved by an +early declared-end completion. The invented 1888 comparison above retains +one refused row of weight 11/5 instead of the literal scan's input error +and zero rows. This module computes no payment; conditional on an otherwise +payable invented $1,000 benefit, an unresolved insured route can determine +whether $0 or $1,000 is payable, but neither amount is adjudicated here. Mutation checks are recorded in [`track_b_insured_status_mutations.json`](track_b_insured_status_mutations.json). diff --git a/docs/design/track_b_insured_status_mutations.json b/docs/design/track_b_insured_status_mutations.json index 01675554f..fc33dc974 100644 --- a/docs/design/track_b_insured_status_mutations.json +++ b/docs/design/track_b_insured_status_mutations.json @@ -2435,5 +2435,185 @@ } ], "round_7_note": "Four isolated in-memory implementation mutations were caught and discarded against the final source. The FRA-attainment-quarter limit, establishment-only FRA limit, one-month-early limit, and unconditional successful-witness short circuit each fail named public-path tests. Every child verified the disk source SHA-256 stayed unchanged. No implementation mutation was written to disk and no existing test assertion was weakened.", - "round_7_final_source_sha256": "fe0d5c32e14d55a85e15890ebb6eb171a2c4e527f17ef7004bab268568001c99" + "round_7_final_source_sha256": "fe0d5c32e14d55a85e15890ebb6eb171a2c4e527f17ef7004bab268568001c99", + "round_8_mutations": [ + { + "name": "remove_declared_end_bound", + "before": " if person.current_disability_period_established:\n # 404.321(b): a pre-1980 period ends after disability ended or at 65.\n last = min(\n last,\n person.current_disability_period_end\n or person.current_disability_period_continues_through\n or person.disability_onset,\n )", + "after": " if person.current_disability_period_established and person.current_disability_period_end is None:\n # 404.321(b): a pre-1980 period ends after disability ended or at 65.\n last = min(\n last,\n person.current_disability_period_end\n or person.current_disability_period_continues_through\n or person.disability_onset,\n )", + "pytest_selectors": [ + "tests/test_track_b_insured_status_fix_round_8.py::test_declared_end_quarter_includes_witness_but_next_quarter_refuses" + ], + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_8.py::test_declared_end_quarter_includes_witness_but_next_quarter_refuses[7-end0]", + "FAILED tests/test_track_b_insured_status_fix_round_8.py::test_declared_end_quarter_includes_witness_but_next_quarter_refuses[7-end1]" + ], + "summary": [ + "2 failed, 2 passed in 8.47s" + ], + "restored": true, + "method": "Isolated in-memory module mutation; implementation file never changed.", + "environment": { + "PYTHONPATH": "$PWD/src:$PWD", + "OMP_NUM_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent-trackb-fix-insured-8", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent-trackb-fix-insured-8", + "PYTHONDONTWRITEBYTECODE": "1" + }, + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent-trackb-fix-insured-8 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent-trackb-fix-insured-8 PYTHONDONTWRITEBYTECODE=1 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\ndigest = hashlib.sha256(original.encode()).hexdigest()\nprint('source_before_sha256', digest)\nbefore = ' if person.current_disability_period_established:\\n # 404.321(b): a pre-1980 period ends after disability ended or at 65.\\n last = min(\\n last,\\n person.current_disability_period_end\\n or person.current_disability_period_continues_through\\n or person.disability_onset,\\n )'\nafter = ' if person.current_disability_period_established and person.current_disability_period_end is None:\\n # 404.321(b): a pre-1980 period ends after disability ended or at 65.\\n last = min(\\n last,\\n person.current_disability_period_end\\n or person.current_disability_period_continues_through\\n or person.disability_onset,\\n )'\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', '--tb=short', 'tests/test_track_b_insured_status_fix_round_8.py::test_declared_end_quarter_includes_witness_but_next_quarter_refuses'])\nassert Path(i.__file__).read_text() == original\nprint('source_after_sha256', hashlib.sha256(Path(i.__file__).read_bytes()).hexdigest())\nraise SystemExit(result)\nPY", + "source_before_sha256": "c8ce8ed630e946c5c46121ed9c26150f6f4744df82066ccbea9ece08069b049d", + "source_after_sha256": "c8ce8ed630e946c5c46121ed9c26150f6f4744df82066ccbea9ece08069b049d" + }, + { + "name": "remove_continuity_bound", + "before": " if person.current_disability_period_established:\n # 404.321(b): a pre-1980 period ends after disability ended or at 65.\n last = min(\n last,\n person.current_disability_period_end\n or person.current_disability_period_continues_through\n or person.disability_onset,\n )", + "after": " if person.current_disability_period_established:\n # 404.321(b): a pre-1980 period ends after disability ended or at 65.\n last = min(\n last,\n person.current_disability_period_end\n or person.disability_onset,\n )", + "pytest_selectors": [ + "tests/test_track_b_insured_status_fix_round_8.py::test_continuity_quarter_includes_witness_but_later_quarter_refuses" + ], + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_8.py::test_continuity_quarter_includes_witness_but_later_quarter_refuses[4]" + ], + "summary": [ + "1 failed, 1 passed in 3.62s" + ], + "restored": true, + "method": "Isolated in-memory module mutation; implementation file never changed.", + "environment": { + "PYTHONPATH": "$PWD/src:$PWD", + "OMP_NUM_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent-trackb-fix-insured-8", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent-trackb-fix-insured-8", + "PYTHONDONTWRITEBYTECODE": "1" + }, + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent-trackb-fix-insured-8 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent-trackb-fix-insured-8 PYTHONDONTWRITEBYTECODE=1 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\ndigest = hashlib.sha256(original.encode()).hexdigest()\nprint('source_before_sha256', digest)\nbefore = ' if person.current_disability_period_established:\\n # 404.321(b): a pre-1980 period ends after disability ended or at 65.\\n last = min(\\n last,\\n person.current_disability_period_end\\n or person.current_disability_period_continues_through\\n or person.disability_onset,\\n )'\nafter = ' if person.current_disability_period_established:\\n # 404.321(b): a pre-1980 period ends after disability ended or at 65.\\n last = min(\\n last,\\n person.current_disability_period_end\\n or person.disability_onset,\\n )'\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', '--tb=short', 'tests/test_track_b_insured_status_fix_round_8.py::test_continuity_quarter_includes_witness_but_later_quarter_refuses'])\nassert Path(i.__file__).read_text() == original\nprint('source_after_sha256', hashlib.sha256(Path(i.__file__).read_bytes()).hexdigest())\nraise SystemExit(result)\nPY", + "source_before_sha256": "c8ce8ed630e946c5c46121ed9c26150f6f4744df82066ccbea9ece08069b049d", + "source_after_sha256": "c8ce8ed630e946c5c46121ed9c26150f6f4744df82066ccbea9ece08069b049d" + }, + { + "name": "unknown_end_uses_query_instead_of_onset", + "before": " if person.current_disability_period_established:\n # 404.321(b): a pre-1980 period ends after disability ended or at 65.\n last = min(\n last,\n person.current_disability_period_end\n or person.current_disability_period_continues_through\n or person.disability_onset,\n )", + "after": " if person.current_disability_period_established:\n # 404.321(b): a pre-1980 period ends after disability ended or at 65.\n last = min(\n last,\n person.current_disability_period_end\n or person.current_disability_period_continues_through\n or month,\n )", + "pytest_selectors": [ + "tests/test_track_b_insured_status_fix_round_8.py::test_unknown_end_keeps_onset_witness_but_refuses_later_quarter" + ], + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_8.py::test_unknown_end_keeps_onset_witness_but_refuses_later_quarter[True]" + ], + "summary": [ + "1 failed, 1 passed in 9.06s" + ], + "restored": true, + "method": "Isolated in-memory module mutation; implementation file never changed.", + "environment": { + "PYTHONPATH": "$PWD/src:$PWD", + "OMP_NUM_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent-trackb-fix-insured-8", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent-trackb-fix-insured-8", + "PYTHONDONTWRITEBYTECODE": "1" + }, + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent-trackb-fix-insured-8 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent-trackb-fix-insured-8 PYTHONDONTWRITEBYTECODE=1 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\ndigest = hashlib.sha256(original.encode()).hexdigest()\nprint('source_before_sha256', digest)\nbefore = ' if person.current_disability_period_established:\\n # 404.321(b): a pre-1980 period ends after disability ended or at 65.\\n last = min(\\n last,\\n person.current_disability_period_end\\n or person.current_disability_period_continues_through\\n or person.disability_onset,\\n )'\nafter = ' if person.current_disability_period_established:\\n # 404.321(b): a pre-1980 period ends after disability ended or at 65.\\n last = min(\\n last,\\n person.current_disability_period_end\\n or person.current_disability_period_continues_through\\n or month,\\n )'\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', '--tb=short', 'tests/test_track_b_insured_status_fix_round_8.py::test_unknown_end_keeps_onset_witness_but_refuses_later_quarter'])\nassert Path(i.__file__).read_text() == original\nprint('source_after_sha256', hashlib.sha256(Path(i.__file__).read_bytes()).hexdigest())\nraise SystemExit(result)\nPY", + "source_before_sha256": "c8ce8ed630e946c5c46121ed9c26150f6f4744df82066ccbea9ece08069b049d", + "source_after_sha256": "c8ce8ed630e946c5c46121ed9c26150f6f4744df82066ccbea9ece08069b049d" + }, + { + "name": "stop_alternate_scan_one_quarter_early", + "before": "_qid(person.disability_onset), min(_qid(last), 1960 * 4 + 2) + 1", + "after": "_qid(person.disability_onset), min(_qid(last), 1960 * 4 + 2)", + "pytest_selectors": [ + "tests/test_track_b_insured_status_fix_round_8.py::test_declared_end_quarter_includes_witness_but_next_quarter_refuses" + ], + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_8.py::test_declared_end_quarter_includes_witness_but_next_quarter_refuses[4-end0]", + "FAILED tests/test_track_b_insured_status_fix_round_8.py::test_declared_end_quarter_includes_witness_but_next_quarter_refuses[4-end1]" + ], + "summary": [ + "2 failed, 2 passed in 11.01s" + ], + "restored": true, + "method": "Isolated in-memory module mutation; implementation file never changed.", + "environment": { + "PYTHONPATH": "$PWD/src:$PWD", + "OMP_NUM_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent-trackb-fix-insured-8", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent-trackb-fix-insured-8", + "PYTHONDONTWRITEBYTECODE": "1" + }, + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent-trackb-fix-insured-8 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent-trackb-fix-insured-8 PYTHONDONTWRITEBYTECODE=1 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\ndigest = hashlib.sha256(original.encode()).hexdigest()\nprint('source_before_sha256', digest)\nbefore = '_qid(person.disability_onset), min(_qid(last), 1960 * 4 + 2) + 1'\nafter = '_qid(person.disability_onset), min(_qid(last), 1960 * 4 + 2)'\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', '--tb=short', 'tests/test_track_b_insured_status_fix_round_8.py::test_declared_end_quarter_includes_witness_but_next_quarter_refuses'])\nassert Path(i.__file__).read_text() == original\nprint('source_after_sha256', hashlib.sha256(Path(i.__file__).read_bytes()).hexdigest())\nraise SystemExit(result)\nPY", + "source_before_sha256": "c8ce8ed630e946c5c46121ed9c26150f6f4744df82066ccbea9ece08069b049d", + "source_after_sha256": "c8ce8ed630e946c5c46121ed9c26150f6f4744df82066ccbea9ece08069b049d" + }, + { + "name": "bound_only_declared_ends", + "before": " if person.current_disability_period_established:\n # 404.321(b): a pre-1980 period ends after disability ended or at 65.\n last = min(\n last,\n person.current_disability_period_end\n or person.current_disability_period_continues_through\n or person.disability_onset,\n )", + "after": " if person.current_disability_period_established and person.current_disability_period_end is not None:\n # 404.321(b): a pre-1980 period ends after disability ended or at 65.\n last = min(\n last,\n person.current_disability_period_end\n or person.current_disability_period_continues_through\n or person.disability_onset,\n )", + "pytest_selectors": [ + "tests/test_track_b_insured_status_fix_round_8.py::test_unknown_end_cannot_return_status_when_declared_completion_refuses" + ], + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_8.py::test_unknown_end_cannot_return_status_when_declared_completion_refuses" + ], + "summary": [ + "1 failed in 319.39s (0:05:19)" + ], + "restored": true, + "method": "Isolated in-memory module mutation; implementation file never changed.", + "environment": { + "PYTHONPATH": "$PWD/src:$PWD", + "OMP_NUM_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent-trackb-fix-insured-8", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent-trackb-fix-insured-8", + "PYTHONDONTWRITEBYTECODE": "1" + }, + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent-trackb-fix-insured-8 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent-trackb-fix-insured-8 PYTHONDONTWRITEBYTECODE=1 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\ndigest = hashlib.sha256(original.encode()).hexdigest()\nprint('source_before_sha256', digest)\nbefore = ' if person.current_disability_period_established:\\n # 404.321(b): a pre-1980 period ends after disability ended or at 65.\\n last = min(\\n last,\\n person.current_disability_period_end\\n or person.current_disability_period_continues_through\\n or person.disability_onset,\\n )'\nafter = ' if person.current_disability_period_established and person.current_disability_period_end is not None:\\n # 404.321(b): a pre-1980 period ends after disability ended or at 65.\\n last = min(\\n last,\\n person.current_disability_period_end\\n or person.current_disability_period_continues_through\\n or person.disability_onset,\\n )'\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', '--tb=short', 'tests/test_track_b_insured_status_fix_round_8.py::test_unknown_end_cannot_return_status_when_declared_completion_refuses'])\nassert Path(i.__file__).read_text() == original\nprint('source_after_sha256', hashlib.sha256(Path(i.__file__).read_bytes()).hexdigest())\nraise SystemExit(result)\nPY", + "source_before_sha256": "c8ce8ed630e946c5c46121ed9c26150f6f4744df82066ccbea9ece08069b049d", + "source_after_sha256": "c8ce8ed630e946c5c46121ed9c26150f6f4744df82066ccbea9ece08069b049d" + }, + { + "name": "bypass_continuity_bound_for_unknown_end", + "before": " if person.current_disability_period_established:\n # 404.321(b): a pre-1980 period ends after disability ended or at 65.\n last = min(\n last,\n person.current_disability_period_end\n or person.current_disability_period_continues_through\n or person.disability_onset,\n )", + "after": " if person.current_disability_period_established and not (\n person.current_disability_period_end is None\n and person.current_disability_period_continues_through is not None\n ):\n # 404.321(b): a pre-1980 period ends after disability ended or at 65.\n last = min(\n last,\n person.current_disability_period_end\n or person.current_disability_period_continues_through\n or person.disability_onset,\n )", + "pytest_selectors": [ + "tests/test_track_b_insured_status_fix_round_8.py::test_continuity_quarter_includes_witness_but_later_quarter_refuses[7]" + ], + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_8.py::test_continuity_quarter_includes_witness_but_later_quarter_refuses[7]" + ], + "summary": [ + "1 failed in 11.69s" + ], + "restored": true, + "method": "Isolated in-memory module mutation; implementation file never changed.", + "environment": { + "PYTHONPATH": "$PWD/src:$PWD", + "OMP_NUM_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent-trackb-fix-insured-8", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent-trackb-fix-insured-8", + "PYTHONDONTWRITEBYTECODE": "1" + }, + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent-trackb-fix-insured-8 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent-trackb-fix-insured-8 PYTHONDONTWRITEBYTECODE=1 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\ndigest = hashlib.sha256(original.encode()).hexdigest()\nprint('source_before_sha256', digest)\nbefore = ' if person.current_disability_period_established:\\n # 404.321(b): a pre-1980 period ends after disability ended or at 65.\\n last = min(\\n last,\\n person.current_disability_period_end\\n or person.current_disability_period_continues_through\\n or person.disability_onset,\\n )'\nafter = ' if person.current_disability_period_established and not (\\n person.current_disability_period_end is None\\n and person.current_disability_period_continues_through is not None\\n ):\\n # 404.321(b): a pre-1980 period ends after disability ended or at 65.\\n last = min(\\n last,\\n person.current_disability_period_end\\n or person.current_disability_period_continues_through\\n or person.disability_onset,\\n )'\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', '--tb=short', 'tests/test_track_b_insured_status_fix_round_8.py::test_continuity_quarter_includes_witness_but_later_quarter_refuses[7]'])\nassert Path(i.__file__).read_text() == original\nprint('source_after_sha256', hashlib.sha256(Path(i.__file__).read_bytes()).hexdigest())\nraise SystemExit(result)\nPY", + "source_before_sha256": "c8ce8ed630e946c5c46121ed9c26150f6f4744df82066ccbea9ece08069b049d", + "source_after_sha256": "c8ce8ed630e946c5c46121ed9c26150f6f4744df82066ccbea9ece08069b049d" + } + ], + "round_8_note": "Six isolated in-memory implementation mutations were caught and discarded against the final source. Removing the declared-end bound, removing the continuity bound, bypassing the continuity ceiling for an UNKNOWN end, substituting query for onset, stopping one quarter early, and binding only declared ends each fail named public-path tests. The continuity removal catches loss of a covered-quarter witness, while bypassing the ceiling catches unsafe extension to a later quarter. The declared-end-only mutation is caught by the UNKNOWN-end completion invariant. Every foreground child verified the disk source SHA-256 stayed unchanged. No implementation mutation was written to disk and no existing assertion was weakened.", + "round_8_final_source_sha256": "c8ce8ed630e946c5c46121ed9c26150f6f4744df82066ccbea9ece08069b049d" } diff --git a/src/populace_dynamics/track_b/insured_status.py b/src/populace_dynamics/track_b/insured_status.py index 42b43d8aa..32e0f3645 100644 --- a/src/populace_dynamics/track_b/insured_status.py +++ b/src/populace_dynamics/track_b/insured_status.py @@ -5,13 +5,18 @@ or forecast claim. Act 213, 214, 216(i), 223(c); 20 CFR 404 subpart B and 404.315/.320/.321; POMS RS 00301. Every year is declared, including zero and unknown years. -Medical onset declares continuous disability through the query month; it +Medical onset declares continuous disability through the query month, +subject to an established historical period's ending under 404.321(b); it never establishes an administrative period of disability. An established period ends no later than the month before full retirement age; an unknown ending includes every candidate end quarter from insured start through query/cap and permitted continuation. The cap never establishes the end. The alternate test's 20/40 exclusion uses only quarters beginning before -the FRA month, whether or not a period is declared established. +the FRA month, whether or not a period is declared established. For an +established period, the witness quarter must also begin by the declared +end, known continuity date, or onset when neither date is known. Where +the literal and period-covered readings of RS00301.480 A differ, the +alternate route retains its named refusal. Dated continuity restricts possible endings without establishing an end; a date beyond the query quarter makes that quarter interior to the period. Disability tests @@ -815,6 +820,14 @@ def _pre1956_alternate_possible( # A witness must allow a freeze or DIB before FRA (Act 216(i)(2)(D), # 404.315(a), 404.321(a)-(b)), regardless of declared establishment. last = min(month, _fra_date(person).replace(day=1) - timedelta(days=1)) + if person.current_disability_period_established: + # 404.321(b): a pre-1980 period ends after disability ended or at 65. + last = min( + last, + person.current_disability_period_end + or person.current_disability_period_continues_through + or person.disability_onset, + ) lower = credits if lower_credits is None else lower_credits # Source conflict us:oasdi-insured-pre1956-alternate-any-quarter-scan for quarter in range( @@ -1581,8 +1594,9 @@ def insured_status( ) -> InsuredStatus: """Decide declared insurance, retaining coverage refusals in denominators. - Medical onset means continuously disabled through this query and never - establishes a period. Declare establishment, prior-period provenance, + Medical onset means continuously disabled through this query, subject + to an established historical period's ending under 404.321(b), and + never establishes a period. Declare establishment, prior-period provenance, and section 214(c) applicability; UNKNOWN never silently means none. Declare an administrative ending with its provenance when known. An observed continues-through date instead excludes earlier endings and @@ -1593,6 +1607,10 @@ def insured_status( query, and the first insured quarter supplies the witness (404.131). An alternate for disability before 1956 is excluded only by 20/40 in a quarter beginning before the FRA month, independently of establishment. + For established periods it must also begin by every completion's + covered date: the declared end, continuity date, or otherwise onset. + Disagreement with the literal any-quarter reading retains the named + alternate refusal; post-1980 endings can differ under 404.321(c). Establishment is an input error only if no ordinary, observable, or flagged specialist route could validate any completion of the facts. History validation runs first. Uncomputable QC rows use bounded diff --git a/tests/README-tiers.md b/tests/README-tiers.md index b2519a8d9..07e25fc36 100644 --- a/tests/README-tiers.md +++ b/tests/README-tiers.md @@ -39,9 +39,9 @@ pytest --collect-only -q -m oracle_policyengine | tail -1 | Tier | Tests at HEAD | |---|---:| -| `unit` | 20,664 | +| `unit` | 20,678 | | `artifact` | 4,271 | | `integration_psid` | 1,471 | | `reproduction_legacy` | 520 | | `oracle_policyengine` | 308 | -| **Total** | **27,234** | +| **Total** | **27,248** | diff --git a/tests/test_track_b_insured_status_fix_round_6_routes.py b/tests/test_track_b_insured_status_fix_round_6_routes.py index 058067083..d822d0e03 100644 --- a/tests/test_track_b_insured_status_fix_round_6_routes.py +++ b/tests/test_track_b_insured_status_fix_round_6_routes.py @@ -76,6 +76,11 @@ def test_twenty_of_forty_before_october_1960_excludes_alternate_refusal(): def test_twenty_of_forty_scan_includes_later_disabled_quarters_before_1960(): person, years, month = _ordinary_pre1956_case() + person = replace( + person, + current_disability_period_end=date(1956, 12, 31), + current_disability_period_end_provenance=OBSERVED, + ) years[1950] = i.CoverageYear(OBSERVED, qc_quarters=(False,) * 4) years[1940] = i.CoverageYear(OBSERVED, qc_quarters=(True,) * 4) years[1956] = i.CoverageYear(OBSERVED, qc_quarters=(True,) * 4) @@ -89,6 +94,11 @@ def test_twenty_of_forty_alternate_exclusion_stops_before_october_1960( quarter, ): person, years, month = _ordinary_pre1956_case() + person = replace( + person, + current_disability_period_end=date(1960, 12, 31), + current_disability_period_end_provenance=OBSERVED, + ) years[1950] = i.CoverageYear(OBSERVED, qc_quarters=(False,) * 4) years[1940] = i.CoverageYear(OBSERVED, qc_quarters=(True,) * 4) years[1955] = i.CoverageYear( @@ -317,18 +327,15 @@ def test_alternate_exclusion_uses_existing_disability_scan_fra_boundary( qc_quarters=tuple(q == twentieth_quarter for q in range(1, 5)), ) assert i._fra_date(person) == date(1953, 5, 1) - if twentieth_quarter == 2: - # The ordinary exclusion is available before FRA, but its first - # insured quarter is later than the fixed 1952 ending. - _assert_invalid_without_row(person, years, month) - else: - # A first ordinary witness after FRA cannot displace the valid - # alternate start in July 1952, before the fixed ending. - row = _row(person, years, month) - assert ( - row.unsupported.reason - is i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956 - ) - assert count_family_outcomes((row,)).unsupported_weight == Fraction( - 11, 5 - ) + # Neither a post-end pre-FRA witness nor a post-FRA witness can + # displace the possible alternate start in July 1952. + row = _row(person, years, month) + assert ( + row.unsupported.reason + is i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956 + ) + denominator = count_family_outcomes((row,)) + assert denominator.rows == denominator.unsupported_rows == 1 + assert ( + denominator.weight == denominator.unsupported_weight == Fraction(11, 5) + ) diff --git a/tests/test_track_b_insured_status_fix_round_8.py b/tests/test_track_b_insured_status_fix_round_8.py new file mode 100644 index 000000000..e6a061249 --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_8.py @@ -0,0 +1,283 @@ +"""Statutory conformance: alternate witnesses must cover every completion. + +Invented declarations and captured rules only. No population, behavioral, +payment, or forecast claim. Every public outcome retains its row and weight. +""" + +import calendar +from dataclasses import replace +from datetime import date, timedelta +from fractions import Fraction + +import pytest +from hypothesis import example, given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as i +from populace_dynamics.track_b.gross_benefits import count_family_outcomes +from tests.test_track_b_insured_status import history +from tests.test_track_b_insured_status_fix_round_6_routes import ( + _ordinary_pre1956_case, +) + +OBSERVED = i.EarningsProvenance.OBSERVED +UNKNOWN = i.EarningsProvenance.UNKNOWN +QUERY = date(1968, 1, 1) +WEIGHT = Fraction(11, 5) +ALTERNATE = i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956 + + +def _case(witness=date(1956, 4, 1), *, fra_month=5, end=None, through=None): + person = i.Person( + date(1895, fra_month, 2), + sex=i.Sex.FEMALE, + disability_onset=date(1955, 7, 15), + current_disability_period_established=True, + current_disability_period_provenance=OBSERVED, + current_disability_period_end=end, + current_disability_period_end_provenance=( + OBSERVED if end is not None else UNKNOWN + ), + current_disability_period_continues_through=through, + current_disability_period_continues_through_provenance=( + OBSERVED if through is not None else UNKNOWN + ), + prior_disability_periods_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + years = history(person, QUERY, {year: 4 for year in range(1951, 1955)}) + years[1940] = i.CoverageYear( + OBSERVED, qc_quarters=(True, False, False, False) + ) + years[1955] = i.CoverageYear( + OBSERVED, qc_quarters=(True, True, True, False) + ) + quarter = (witness.month - 1) // 3 + years[witness.year] = i.CoverageYear( + OBSERVED, qc_quarters=tuple(q == quarter for q in range(4)) + ) + return person, years + + +def _row(person, years, *, test=i.InsuredTest.FULLY): + return i.evaluate_insured_status( + "round-eight-covered-witness", + WEIGHT, + lambda: i.insured_status(person, years, QUERY, test=test), + ) + + +def _assert_row(row, *, refused): + counts = count_family_outcomes((row,)) + assert counts.rows == 1 + assert counts.weight == WEIGHT + if refused: + assert row.result is None + assert row.unsupported.reason is ALTERNATE + assert counts.unsupported_rows == 1 + assert counts.unsupported_weight == WEIGHT + else: + assert row.unsupported is None + assert counts.unsupported_rows == 0 + assert counts.unsupported_weight == 0 + decision = row.result.fully or row.result.disability + assert decision.insured + + +@pytest.mark.parametrize("end", [date(1956, 6, 30), date(1956, 5, 31)]) +@pytest.mark.parametrize("witness_month", [4, 7]) +def test_declared_end_quarter_includes_witness_but_next_quarter_refuses( + end, witness_month +): + person, years = _case(date(1956, witness_month, 1), end=end) + row = _row(person, years) + _assert_row(row, refused=witness_month == 7) + if witness_month == 4: + assert row.result.current_disability_period_start == date(1956, 4, 1) + + +@pytest.mark.parametrize("later", [False, True]) +def test_unknown_end_keeps_onset_witness_but_refuses_later_quarter(later): + # Round 5's birth-1920 case already has 20/40 in the onset quarter. + person, years, _ = _ordinary_pre1956_case() + if later: + years[1950] = i.CoverageYear( + OBSERVED, qc_quarters=(False, True, True, True) + ) + years[1940] = i.CoverageYear(OBSERVED, qc_quarters=(True,) * 4) + years[1955] = i.CoverageYear( + OBSERVED, qc_quarters=(False, True, False, False) + ) + row = _row(person, years) + _assert_row(row, refused=later) + if not later: + assert row.result.current_disability_period_start == date(1955, 1, 15) + + +@pytest.mark.parametrize("witness_month", [4, 7]) +def test_continuity_quarter_includes_witness_but_later_quarter_refuses( + witness_month, +): + person, years = _case( + date(1956, witness_month, 1), through=date(1956, 5, 15) + ) + _assert_row(_row(person, years), refused=witness_month == 7) + + +def test_later_disabled_quarters_with_unknown_end_keep_named_refusal(): + person, years, _ = _ordinary_pre1956_case() + years[1950] = i.CoverageYear(OBSERVED, qc_quarters=(False,) * 4) + years[1940] = i.CoverageYear(OBSERVED, qc_quarters=(True,) * 4) + years[1956] = i.CoverageYear(OBSERVED, qc_quarters=(True,) * 4) + _assert_row(_row(person, years), refused=True) + + +@pytest.mark.parametrize("quarter", [3, 4]) +def test_october_1960_boundary_with_unknown_end_keeps_named_refusal(quarter): + person, years, _ = _ordinary_pre1956_case() + years[1950] = i.CoverageYear(OBSERVED, qc_quarters=(False,) * 4) + years[1940] = i.CoverageYear(OBSERVED, qc_quarters=(True,) * 4) + years[1955] = i.CoverageYear( + OBSERVED, qc_quarters=(True, True, True, False) + ) + years[1960] = i.CoverageYear( + OBSERVED, qc_quarters=tuple(q == quarter for q in range(1, 5)) + ) + _assert_row(_row(person, years), refused=True) + + +def test_round_seven_declared_end_comparison_retains_named_refusal(): + person = i.Person( + date(1888, 5, 2), + sex=i.Sex.FEMALE, + disability_onset=date(1952, 7, 15), + current_disability_period_established=True, + current_disability_period_provenance=OBSERVED, + current_disability_period_end=date(1952, 9, 30), + current_disability_period_end_provenance=OBSERVED, + prior_disability_periods_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + years = history( + person, QUERY, {1938: 2, 1944: 4, 1945: 4, 1946: 4, 1951: 4} + ) + years[1952] = i.CoverageYear( + OBSERVED, qc_quarters=(True, True, False, True) + ) + years[1953] = i.CoverageYear( + OBSERVED, qc_quarters=(False, True, False, False) + ) + _assert_row(_row(person, years), refused=True) + + +@settings(max_examples=30, deadline=None) +@example( + mode="declared", + covered=date(1956, 5, 31), + witness_year=1956, + witness_quarter=3, + fra_month=5, +) +@example( + mode="continuity", + covered=date(1956, 5, 31), + witness_year=1956, + witness_quarter=3, + fra_month=5, +) +@example( + mode="unknown", + covered=date(1956, 5, 31), + witness_year=1956, + witness_quarter=2, + fra_month=5, +) +@example( + mode="declared", + covered=date(1960, 12, 31), + witness_year=1960, + witness_quarter=4, + fra_month=12, +) +@example( + mode="declared", + covered=date(1960, 5, 31), + witness_year=1960, + witness_quarter=2, + fra_month=4, +) +@example( + mode="continuity", + covered=date(1956, 5, 31), + witness_year=1956, + witness_quarter=2, + fra_month=5, +) +@given( + mode=st.sampled_from(["declared", "unknown", "continuity"]), + covered=st.dates(min_value=date(1955, 7, 31), max_value=date(1960, 1, 31)), + witness_year=st.sampled_from([1956, 1959, 1960]), + witness_quarter=st.integers(1, 4), + fra_month=st.integers(1, 12), +) +def test_independent_date_oracle_classifies_covered_quarters_both_directions( + mode, covered, witness_year, witness_quarter, fra_month +): + # The oracle uses plain dates only. No production quarter, FRA, coverage, + # possibility, or witness helper participates in its expected result. + fra_month_start = date(1960, fra_month, 1) + if mode == "continuity": + covered = min(covered, fra_month_start - timedelta(days=1)) + if mode == "declared": + covered = date( + covered.year, + covered.month, + calendar.monthrange(covered.year, covered.month)[1], + ) + if mode == "unknown": + covered = date(1955, 7, 15) + witness = date(witness_year, (witness_quarter - 1) * 3 + 1, 1) + excludes = ( + witness <= covered + and witness < fra_month_start + and witness < date(1960, 10, 1) + ) + person, years = _case( + witness, + fra_month=fra_month, + end=covered if mode == "declared" else None, + through=covered if mode == "continuity" else None, + ) + row = _row(person, years) + _assert_row(row, refused=not excludes) + assert (row.result is not None) == excludes + assert (row.unsupported is not None) == (not excludes) + + +@settings(max_examples=12, deadline=None) +@given(witness_month=st.integers(1, 12), ending_month=st.integers(7, 12)) +def test_unknown_end_cannot_return_status_when_declared_completion_refuses( + witness_month, ending_month +): + person, years = _case(date(1956, witness_month, 1)) + endings = ( + date(1955, ending_month, calendar.monthrange(1955, ending_month)[1]), + date(1956, 12, 31), + ) + completions = [ + _row( + replace( + person, + current_disability_period_end=end, + current_disability_period_end_provenance=OBSERVED, + ), + years, + ) + for end in endings + ] + assert any(row.unsupported is not None for row in completions) + for row in completions: + _assert_row(row, refused=row.unsupported is not None) + _assert_row(_row(person, years), refused=True) diff --git a/tests/tier_counts.json b/tests/tier_counts.json index 167673fa4..7faef98f1 100644 --- a/tests/tier_counts.json +++ b/tests/tier_counts.json @@ -1,7 +1,7 @@ { "schema_version": 1, "counts": { - "unit": 20664, + "unit": 20678, "artifact": 4271, "integration_psid": 1471, "reproduction_legacy": 520, From 7c5ed6bec2c7c481d34bd0c96f4779dcea7137da Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sat, 31 Oct 2026 14:16:36 -0400 Subject: [PATCH 14/46] Refuse by name when UNKNOWN establishment hides the pre-1956 alternate (#562 round 9) Round 8 made an UNKNOWN end hold for every completion, but UNKNOWN establishment still computed DISABILITY from a later ordinary witness. An established completion can end before that witness, and such a completion is valid only through the RS 00301.480 alternate route, so its status turns on application conditions the rule doesn't model. DISABILITY=True therefore didn't hold for every completion. UNKNOWN establishment now takes the same covered-date bound as an established period. The schema forbids an end or continuity date without establishment, so the bound comes to onset: a 20/40 witness in the onset quarter still excludes the route, and a later one doesn't. A later positive witness no longer returns before the alternate check. FULLY and CURRENTLY keep their results, because favorable disregard rests on credits that no completion's period can remove. Declared absence has no completions to disagree with, and an onset at or after FRA admits none. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 109 +++++-- .../track_b_insured_status_mutations.json | 96 ++++++- .../track_b/insured_status.py | 37 ++- tests/README-tiers.md | 4 +- ...test_track_b_insured_status_fix_round_7.py | 13 +- ...test_track_b_insured_status_fix_round_9.py | 265 ++++++++++++++++++ tests/tier_counts.json | 2 +- 7 files changed, 480 insertions(+), 46 deletions(-) create mode 100644 tests/test_track_b_insured_status_fix_round_9.py diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index b66e29980..a024adb3f 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -97,8 +97,8 @@ explicitly means no established periods. The default provenance is `disability_onset` supplies the ordinary continuous-disability premise from that day through the query month; the rule does not adjudicate recovery. -A declared historical period end can limit the alternate-pre1956 scan, -as required by 404.321(b) below. Onset may +A declared historical period end or an UNKNOWN establishment completion +can limit the alternate-pre1956 scan, as required by 404.321(b) below. Onset may be later within the query month, but not in a later month. Onset alone never establishes a period or freezes elapsed years. With an onset, the caller must explicitly declare `current_disability_period_provenance` and @@ -132,9 +132,12 @@ periods, from onset through the earliest of the query, 1960Q3, and the quarter containing the last day of the month before FRA. For an established current period it also stops at the declared end, or, with an UNKNOWN end, the continuity date if supplied and otherwise onset. These are the dates -through which every ending completion still covers the period. The FRA -bound -applies regardless of whether a period is declared established: the +through which every ending completion still covers the period. For UNKNOWN +establishment before FRA, an established completion may end in the onset +quarter. The schema permits neither an end nor a continuity date without +establishment, so onset supplies the same covered-date bound. Declared +absence has no established completions and keeps its ordinary result. +The FRA bound applies regardless of whether a period is declared established: the witness must support a freeze or DIB (Act 216(i)(2)(D); 404.315(a); 404.321(a)–(b)). A quarter beginning before the FRA month remains eligible when FRA falls in its second or third month. A witness in the quarter @@ -156,8 +159,9 @@ the literal scan, while "though under a disability" and "for freeze or DIB" support limiting a witness to the period it could establish. A witness after a declared end cannot start that period. Where those readings differ, the rule retains `disability_before_1956_unsupported`; it does not decide -between them. The same protection applies to UNKNOWN endings: an early -ending completion that preserves the route prevents a universal exclusion. +between them. The same protection applies to UNKNOWN endings and UNKNOWN +establishment: an early ending completion that preserves the route prevents +a universal exclusion of that route for DISABILITY. If some feasible fillings still lack 20/40, application facts remain absent and the alternate possibility retains its refusal. On the ordinary route, a valid @@ -383,21 +387,29 @@ another test cannot hide an otherwise decidable answer. No convention is inferred. Every convention-filled year and its identifier is disclosed even if it is outside the decisive recent-work window. -For unknown prior or current establishment facts, ordinary covered-credit -status under favorable disregard of those periods is a sound Boolean -lower bound, including when current establishment is known but its start -depends on unknown prior periods. Section +For unknown prior or current establishment facts, ordinary FULLY and +CURRENTLY covered-credit statuses under favorable disregard of those +periods are sound Boolean lower bounds, including when current establishment +is known but its start depends on unknown prior periods. A DISABILITY +witness additionally requires disability in its tested quarter. Section 404.130(f) permits favorable all-period disregard for the disability window; 404.320(a) supplies the broader rule: "If benefits payable on your earnings record would be denied or reduced because of a period of disability, the period of disability will not be taken into consideration." Railroad and noncreditable military credits remain refused, preserving -RS .120's exception. A true lower bound therefore decides true. For valid -declarations, fewer +RS .120's exception. For FULLY and CURRENTLY, a true lower bound therefore +decides true: their ordinary covered-credit witness survives favorable +disregard regardless of a current period's ending. DISABILITY instead +requires disability in its witness quarter. With UNKNOWN establishment, an +early-ending completion can remove a later ordinary witness and leave only +the alternate route with unmodeled application conditions. The alternate +refusal precedes that prospective true result. For valid declarations, fewer than six maximum feasible lifetime QCs decides false. Otherwise unknown periods may change a false result, so the rule refuses by name. Current -establishment does not change the disability qualification scan that must -prove its start; using its own exclusion would be circular. +establishment still supplies no exclusions to the ordinary disability +qualification scan that must prove its own start; using its own exclusion +would be circular. The alternate-route guard separately protects UNKNOWN +establishment completions with an early ending. `DLIRange.lower` and `.upper` are last-quarter-end dates; `None` is the bottom bound meaning no insured quarter. Without an exit declaration, this @@ -483,7 +495,14 @@ proof finds a possible filling or reaches an unresolved coverage limit, the first original conversion refusal in year order is raised unchanged. Proved impossibility instead raises `InvalidFamilyInput`. With no deferred reason, the existing specialist, date, applicability, and requested-status -checks follow. The evaluator validates its +checks follow. In the requested-status checks, a positive ordinary +DISABILITY witness does not bypass the observable alternate route when +current establishment is UNKNOWN and onset precedes the FRA month. Its +20/40 exclusion must hold even for a completion ending in the onset quarter. +FULLY and CURRENTLY keep favorable-disregard true results; a false CURRENTLY +result can still refuse for unknown establishment before ALL reaches +DISABILITY. No established completion exists for onset in or after the FRA +month, so this correction does not apply there. The evaluator validates its key, weight, and callback before invoking the callback; it adds no statutory refusal of its own. It counts a genuine callback refusal only after the callback's declaration validation has had this opportunity to reject the @@ -624,14 +643,14 @@ to a statutory sentence that does not state it. | --- | --- | | U1. UNKNOWN prior history can collapse to empty solely for impossibility validation when no earliest prior period could start insured, on/after birth, before current onset and the FRA end. | C320(b)(2) and C321(a) require an insured beginning without a still-earlier period. A216(i)(2)(A) permits "five full calendar months' duration or" DIB entitlement "for one or more months". The scan therefore admits a one-month period and maximum feasible earnings. Any possible ordinary or specialist starting route stops the proof. It establishes no observed empty-history fact. | | U2. UNKNOWN current establishment needs no new-period alternative if there is no medical onset or onset is at/after the statutory latest starting month. | A216(i)(2)(A)-(D) and C321 prohibit a period without disability or a nonempty pre-FRA interval. This removes an impossible new-period alternative only; it does not remove UNKNOWN prior history or an existing period's UNKNOWN administrative end. | -| U3. With unknown prior/current periods, true ordinary status under favorable all-period disregard decides true. | C320(a): "If benefits ... would be denied or reduced because of a period of disability, the period of disability will not be taken into consideration." B404.130(f) also permits counting all prior quarters if favorable. RS .120 requires all periods used or all disregarded; selective exclusions are not assumed. Specialist credit regimes are refused first. | +| U3. With unknown prior/current periods, true ordinary FULLY and CURRENTLY status under favorable all-period disregard decides true. A DISABILITY witness must also survive any current-establishment completion that ends the disability before that witness. | C320(a): "If benefits ... would be denied or reduced because of a period of disability, the period of disability will not be taken into consideration." B404.130(f) also permits counting all prior quarters if favorable. RS .120 requires all periods used or all disregarded; selective exclusions are not assumed. Specialist credit regimes are refused first. | | U4. With unknown periods, fewer than six maximum feasible QCs decides false only on the ordinary route after specialist possibilities are excluded. | B404.110(b)(1) and B404.130(a) supply the six-QC prerequisite. U3's disregard cannot manufacture credits. Deemed, transitional, foreign, military/railroad, and automatically revealed historical alternatives retain named refusals instead of using this ordinary collapse. | | U5. UNKNOWN earnings decide a requested Boolean only if all lower/upper ordinary earnings witnesses agree, under the permitted fixed-period/all-period treatments; an uncertain established start refuses only after at least one feasible filling survives. | B404.143 credits one QC for each increment, maximum four; B404.130 and .146 supply assignment/exclusion rules. Adding ordinary QCs cannot invalidate a fixed treatment. A derived start cannot be silently held fixed when the completion changes it. If a lower or upper representative cannot construct the declared period, but another single filling meets its end, continuity, and prior-overlap constraints, the public result is `unknown_earnings_years_decide_status`. If no ordinary filling can qualify by the declared end and all independent routes are impossible, it is an input error and creates no row. A deferred raw-conversion row uses temporary unknown fillings only for possibility, then retains its conversion refusal. Specialist possibilities and administrative-end candidates are considered separately. | | U6. UNKNOWN administrative end decides a status only when every end-quarter candidate from start through query/cap, plus permitted continuation, agrees, after applying any continuity lower bound. | A216(i)(2)(D) uses "whichever ... is the earlier"; C321(c)(3) includes "the last month for which you received benefits" after substantial gainful activity. Medical continuity cannot exclude early ends; a dated administrative continuity observation can. FRA/death caps limit the latest candidate and do not turn the unknown into a fact. Both ending and prior-history unknown facts remain disclosed when both are missing; UNKNOWN prior history uses the universal envelopes rather than inventing a derived current period to enumerate. An actual supplied end keeps its declared-date semantics; known ending provenance requires an ending date. | | U7. UNKNOWN SSPA applicability preserves an ordinary QC-only false status, but never a QC-only true status. | RS .102 B.2 says the worker "must meet one of the following additional requirements" and may fail "even if" the QC requirement is met. Applicability can remove ordinary insurance and cannot supply missing QCs. Known applicability retains adjudication refusal; any separate specialist path is refused first. | | U8. With UNKNOWN prior history, a known current period's start is certain onset only if the lower-credit favorable-disregard witness already insures at onset; otherwise the start stays unknown. | A216(i)(2)(C) and C321(a) make insured onset the earliest legal start. C320(a)'s disregard permits that witness, and no route can move this period before medical onset. Other potentially valid histories prevent an impossibility error but do not fabricate a start. | | U9. A continues-through observation removes only candidate administrative ends before its date; it never supplies an ending endpoint or removes UNKNOWN-end disclosure. | C321(c) enumerates actual ending events. Observation of a period still in force supplies a lower bound on those events, not their occurrence. Same-quarter ends remain possible, while a later-quarter observation makes the query quarter interior. | -| U10. An automatic alternate-pre1956 possibility can be removed for every filling only when the lower-credit filling already has ordinary 20/40 in a quarter covered by every ending completion, before October 1960. | RS .480 A makes the test available only to a disabled worker who "does not have 20/40 for freeze or DIB in any quarter before 10/60". Ordinary fixed-treatment recent-credit counts are monotone in added credits. The scan uses the ordinary 40-quarter window with favorable all-period use/disregard, from onset through the earliest of query, 1960Q3, and the quarter containing the last day of the month before FRA, for every person (A216(i)(2)(D), C315(a), C321(a)–(b)). A quarter stays eligible if FRA falls in its second or third month. It does not substitute the young-worker or blindness rule. For established current periods it additionally ends at the declared end, or the continuity date when the end is UNKNOWN, or onset when both are UNKNOWN. C321(b) governs pre-December-1980 endings; its earlier ending is tied to ended disability rather than an independent administrative event. RS .480 A's "any quarter" supports a literal wider scan, but "though under a disability" and "for freeze or DIB" support excluding post-period witnesses. Where they differ, retain the named alternate refusal. Only a lower-credit 20/40 witness shared by every period-ending completion excludes the alternate for every completion; an upper-only witness cannot do so. Application facts remain absent and are not inferred from this exclusion. The same guard is used for current-establishment and earliest-prior-history possibilities. | +| U10. An automatic alternate-pre1956 possibility can be removed for every filling only when the lower-credit filling already has ordinary 20/40 in a quarter covered by every ending completion, before October 1960. | RS .480 A makes the test available only to a disabled worker who "does not have 20/40 for freeze or DIB in any quarter before 10/60". Ordinary fixed-treatment recent-credit counts are monotone in added credits. The scan uses the ordinary 40-quarter window with favorable all-period use/disregard, from onset through the earliest of query, 1960Q3, and the quarter containing the last day of the month before FRA, for every person (A216(i)(2)(D), C315(a), C321(a)–(b)). A quarter stays eligible if FRA falls in its second or third month. It does not substitute the young-worker or blindness rule. For established current periods it additionally ends at the declared end, or the continuity date when the end is UNKNOWN, or onset when both are UNKNOWN. UNKNOWN establishment before the FRA month uses onset, because neither an end nor continuity can accompany that declaration and an established completion may end in the onset quarter. C321(b) governs pre-December-1980 endings; its earlier ending is tied to ended disability rather than an independent administrative event. RS .480 A's "any quarter" supports a literal wider scan, but "though under a disability" and "for freeze or DIB" support excluding post-period witnesses. Where they differ, retain the named alternate refusal. Only a lower-credit 20/40 witness shared by every period-ending completion excludes the alternate for every completion; an upper-only witness cannot do so. Application facts remain absent and are not inferred from this exclusion. The same guard is used for current-establishment and earliest-prior-history possibilities. | | ID and bound | Captured text and alternative-route defense | | --- | --- | @@ -816,7 +835,7 @@ Round 7 pins the eligibility boundary independently of the ordinary scan: | Invariant | Executing tests | | --- | --- | | For the round-7 cases, whose declared ends are the month before FRA, a 20/40 witness excludes the alternate exactly when its quarter begins before the FRA month and before October 1960, over all twelve FRA months and witness quarters. An earlier period-covered bound can further restrict exclusion, as pinned in round 8. Exclusion yields the ordinary result or a genuinely impossible declaration; non-exclusion preserves the named refusal, one evaluator row, and weight 7/3. | `test_independent_date_oracle_classifies_both_alternate_scan_directions` (Hypothesis with an independent date oracle); `test_fra_quarter_stays_only_when_it_begins_before_fra_month` | -| Established, absent, and UNKNOWN current-period declarations share the same FRA exclusion bound. Successful ordinary pre-FRA neighbours retain their results. | `test_unestablished_period_keeps_alternate_after_fra`; `test_unestablished_period_pre_fra_neighbour_keeps_ordinary_result`; `test_reviewed_fra_neighbours_preserve_their_public_results` | +| Established, absent, and UNKNOWN current-period declarations share the same FRA exclusion bound. Declared-absent ordinary pre-FRA neighbours retain their results; round 9 corrects the UNKNOWN-establishment DISABILITY neighbour. | `test_unestablished_period_keeps_alternate_after_fra`; `test_unestablished_period_pre_fra_neighbour_keeps_ordinary_result`; `test_reviewed_fra_neighbours_preserve_their_public_results` | | The reviewed FRA-month witness retains the historical refusal and exact denominator weight under the ordinary query and OP12 exit; a deferred 1937 conversion retains its original reason instead. | `test_fra_month_witness_keeps_reviewed_refusal_and_denominator` | Round 8 limits exclusion to quarters covered by every ending completion: @@ -827,17 +846,47 @@ Round 8 limits exclusion to quarters covered by every ending completion: | If any declared-end completion preserves the named alternate refusal, an UNKNOWN ending returns no status. An onset-quarter witness remains shared by every completion; a witness in a later quarter without continuity does not. | `test_unknown_end_cannot_return_status_when_declared_completion_refuses` (Hypothesis); `test_unknown_end_keeps_onset_witness_but_refuses_later_quarter` | | The round-7 comparison's ordinary witness after the declared end preserves `disability_before_1956_unsupported`, one evaluator row, and exact weight 11/5. It cannot prove invalidity under every defensible reading. | `test_round_seven_declared_end_comparison_retains_named_refusal`; `test_alternate_exclusion_uses_existing_disability_scan_fra_boundary` | -The UNKNOWN-end completion invariant does not establish the corresponding -claim for UNKNOWN establishment. The round-7 pre-FRA neighbour born May 2, -1895, with onset July 15, 1955 and first 20/40 in 1960Q2 still computes -ordinary disability insurance when establishment is UNKNOWN. Its -established completion with an early September 30, 1955 end instead -retains the alternate refusal. The successful ordinary short circuit in -`_observable_coverage_paths` precedes that prospective established-period -check. `test_unestablished_period_pre_fra_neighbour_keeps_ordinary_result` -pins the unchanged UNKNOWN-establishment result; the round-8 report records -this separate discrepancy and its conflict with the instruction to preserve -that existing expectation. +Round 9 extends the completion invariant to UNKNOWN establishment. The +invented round-7 neighbour has birth May 2, 1895, onset July 15, 1955 and +first 20/40 in 1960Q2. An established completion with an UNKNOWN end or an +early September 30, 1955 end retains the alternate refusal, because the +later witness does not cover every possible period. UNKNOWN establishment +therefore returns `disability_before_1956_unsupported` for DISABILITY, +retaining one row and weight 7/3. FULLY still computes true: its credit +witness survives favorable disregard under 404.130(f) and 404.320(a). +CURRENTLY and ALL retain +`unknown_current_disability_period_decides_status`; ALL encounters the +CURRENTLY refusal first. Declared absence keeps all four existing outcomes. +The split round-7 regression changes only its former `[unknown]` case. + +Both new decision sites use the same UNKNOWN-establishment predicate as +`insured_status`, including onset before the FRA month. Onset at or after +that boundary admits no established completion (premise U2), so neither +site applies the new restriction there. The FRA bound, established-period +covered-date bound, event scan, and repeated-work cost are unchanged. +The rule continues to adopt neither reading of RS .480 A. + +A separate prior-history audit found no corresponding disagreement. An +invented May 2, 1895 birth has two 1940Q1–Q2 credits, every 1951–1954 +quarter, 1955Q1–Q3, and 1960Q2, with zeros elsewhere. A possible prior +April 15–June 30, 1955 period has 20 lifetime QCs, every preceding +post-1950 quarter, and fewer than 20/40, so its starting route can be the +alternate subject to unmodeled application conditions. With current +establishment declared absent and onset July 15, 1955 or January 15, 1956, +UNKNOWN prior history, known empty history, and that supplied prior period +all preserve true DISABILITY and FULLY witnesses. The supplied prior +period is an adjudicated input; favorable disregard under 404.130(f) does +not end the current disabled interval. UNKNOWN prior CURRENTLY and ALL +retain their named unknown-prior refusal. With current establishment +ending September 30, 1955, all three histories instead preserve the +alternate refusal. The reproducible invented probe checks 28 public rows, +including all refusal weights; it justifies no prior-history code change. + +| Invariant | Executing tests | +| --- | --- | +| If any established completion retains the alternate refusal, UNKNOWN establishment returns no DISABILITY status. If every established completion computes the same DISABILITY status and declared absence agrees, UNKNOWN does not refuse the alternate route. Every outcome retains one row and exact weight 7/3. | `test_unknown_establishment_cannot_compute_when_completion_refuses`; `test_unknown_establishment_keeps_agreed_completion_status` (Hypothesis) | +| The independent date oracle excludes the alternate under UNKNOWN establishment exactly when the lower-credit 20/40 witness begins in the onset quarter, before the FRA month and October 1960. Later witnesses preserve the refusal. | `test_independent_date_oracle_classifies_unknown_establishment_both_ways` (Hypothesis and explicit boundary examples); `test_unknown_establishment_refuses_witness_one_quarter_after_onset` | +| On the reviewed neighbour, UNKNOWN DISABILITY refuses the alternate, FULLY remains true, CURRENTLY and ALL retain their existing unknown-current refusal, and declared absence keeps all four results. The onset-quarter witness, post-1955 onset, and onset at or after FRA retain their public outcomes. | `test_reviewed_status_table_retains_rows_and_weights`; `test_unknown_fully_keeps_favorable_ordinary_witness`; `test_unknown_establishment_keeps_round_five_onset_quarter_witness`; `test_unknown_establishment_post1955_onset_keeps_ordinary_status`; `test_unknown_establishment_at_or_after_fra_keeps_existing_refusal` | The invented boundary example has birth April 2, 1895, female sex, onset July 15, 1955, and an observed established period ending March 31, 1960. diff --git a/docs/design/track_b_insured_status_mutations.json b/docs/design/track_b_insured_status_mutations.json index fc33dc974..563903113 100644 --- a/docs/design/track_b_insured_status_mutations.json +++ b/docs/design/track_b_insured_status_mutations.json @@ -2615,5 +2615,99 @@ } ], "round_8_note": "Six isolated in-memory implementation mutations were caught and discarded against the final source. Removing the declared-end bound, removing the continuity bound, bypassing the continuity ceiling for an UNKNOWN end, substituting query for onset, stopping one quarter early, and binding only declared ends each fail named public-path tests. The continuity removal catches loss of a covered-quarter witness, while bypassing the ceiling catches unsafe extension to a later quarter. The declared-end-only mutation is caught by the UNKNOWN-end completion invariant. Every foreground child verified the disk source SHA-256 stayed unchanged. No implementation mutation was written to disk and no existing assertion was weakened.", - "round_8_final_source_sha256": "c8ce8ed630e946c5c46121ed9c26150f6f4744df82066ccbea9ece08069b049d" + "round_8_final_source_sha256": "c8ce8ed630e946c5c46121ed9c26150f6f4744df82066ccbea9ece08069b049d", + "round_9_mutations": [ + { + "name": "restore_positive_disability_return_for_unknown_establishment", + "before": " and not _current_period_establishment_unknown(person)\n", + "after": "", + "pytest_selectors": [ + "tests/test_track_b_insured_status_fix_round_9.py::test_reviewed_status_table_retains_rows_and_weights[InsuredTest.DISABILITY-unknown]" + ], + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_9.py::test_reviewed_status_table_retains_rows_and_weights[InsuredTest.DISABILITY-unknown]" + ], + "summary": [ + "1 failed in 4.39s" + ], + "restored": true, + "method": "Isolated in-memory module mutation; implementation file never changed.", + "environment": { + "PYTHONPATH": "$PWD/src:$PWD", + "OMP_NUM_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/trackb-round9-psid", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/trackb-round9-epuf", + "PYTHONDONTWRITEBYTECODE": "1" + }, + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round9-psid POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round9-epuf PYTHONDONTWRITEBYTECODE=1 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\nprint('source_before_sha256', hashlib.sha256(original.encode()).hexdigest())\nbefore = \" and not _current_period_establishment_unknown(person)\\n\"\nafter = \"\"\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', '--tb=short', \"tests/test_track_b_insured_status_fix_round_9.py::test_reviewed_status_table_retains_rows_and_weights[InsuredTest.DISABILITY-unknown]\"])\nassert Path(i.__file__).read_text() == original\nprint('source_after_sha256', hashlib.sha256(Path(i.__file__).read_bytes()).hexdigest())\nraise SystemExit(result)\nPY", + "source_before_sha256": "2cc1ffae363bc7334d5e50fdc088b858ab60a28130cde20fa581690088459aa5", + "source_after_sha256": "2cc1ffae363bc7334d5e50fdc088b858ab60a28130cde20fa581690088459aa5", + "output_file": "scratch/review/round-9-mutation-restore_positive_disability_return_for_unknown_establishment.txt" + }, + { + "name": "drop_unknown_establishment_from_covered_date_bound", + "before": " if (\n person.current_disability_period_established\n or _current_period_establishment_unknown(person)\n ):\n # 404.321(b):", + "after": " if person.current_disability_period_established:\n # 404.321(b):", + "pytest_selectors": [ + "tests/test_track_b_insured_status_fix_round_9.py::test_unknown_establishment_refuses_witness_one_quarter_after_onset" + ], + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_9.py::test_unknown_establishment_refuses_witness_one_quarter_after_onset" + ], + "summary": [ + "1 failed in 2.39s" + ], + "restored": true, + "method": "Isolated in-memory module mutation; implementation file never changed.", + "environment": { + "PYTHONPATH": "$PWD/src:$PWD", + "OMP_NUM_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/trackb-round9-psid", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/trackb-round9-epuf", + "PYTHONDONTWRITEBYTECODE": "1" + }, + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round9-psid POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round9-epuf PYTHONDONTWRITEBYTECODE=1 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\nprint('source_before_sha256', hashlib.sha256(original.encode()).hexdigest())\nbefore = \" if (\\n person.current_disability_period_established\\n or _current_period_establishment_unknown(person)\\n ):\\n # 404.321(b):\"\nafter = \" if person.current_disability_period_established:\\n # 404.321(b):\"\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', '--tb=short', \"tests/test_track_b_insured_status_fix_round_9.py::test_unknown_establishment_refuses_witness_one_quarter_after_onset\"])\nassert Path(i.__file__).read_text() == original\nprint('source_after_sha256', hashlib.sha256(Path(i.__file__).read_bytes()).hexdigest())\nraise SystemExit(result)\nPY", + "source_before_sha256": "2cc1ffae363bc7334d5e50fdc088b858ab60a28130cde20fa581690088459aa5", + "source_after_sha256": "2cc1ffae363bc7334d5e50fdc088b858ab60a28130cde20fa581690088459aa5", + "output_file": "scratch/review/round-9-mutation-drop_unknown_establishment_from_covered_date_bound.txt" + }, + { + "name": "apply_unknown_alternate_refusal_to_fully", + "before": " if (\n person.current_disability_period_established\n and _pre1956_alternate_possible(", + "after": " if (\n (person.current_disability_period_established\n or _current_period_establishment_unknown(person))\n and _pre1956_alternate_possible(", + "pytest_selectors": [ + "tests/test_track_b_insured_status_fix_round_9.py::test_unknown_fully_keeps_favorable_ordinary_witness" + ], + "returncode": 1, + "failed_tests": [ + "FAILED tests/test_track_b_insured_status_fix_round_9.py::test_unknown_fully_keeps_favorable_ordinary_witness" + ], + "summary": [ + "1 failed in 5.01s" + ], + "restored": true, + "method": "Isolated in-memory module mutation; implementation file never changed.", + "environment": { + "PYTHONPATH": "$PWD/src:$PWD", + "OMP_NUM_THREADS": "1", + "OMP_WAIT_POLICY": "PASSIVE", + "POLARS_MAX_THREADS": "1", + "POPULACE_DYNAMICS_PSID_DIR": "/nonexistent/trackb-round9-psid", + "POPULACE_DYNAMICS_EPUF_DIR": "/nonexistent/trackb-round9-epuf", + "PYTHONDONTWRITEBYTECODE": "1" + }, + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round9-psid POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round9-epuf PYTHONDONTWRITEBYTECODE=1 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\noriginal = Path(i.__file__).read_text()\nprint('source_before_sha256', hashlib.sha256(original.encode()).hexdigest())\nbefore = \" if (\\n person.current_disability_period_established\\n and _pre1956_alternate_possible(\"\nafter = \" if (\\n (person.current_disability_period_established\\n or _current_period_establishment_unknown(person))\\n and _pre1956_alternate_possible(\"\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', '--tb=short', \"tests/test_track_b_insured_status_fix_round_9.py::test_unknown_fully_keeps_favorable_ordinary_witness\"])\nassert Path(i.__file__).read_text() == original\nprint('source_after_sha256', hashlib.sha256(Path(i.__file__).read_bytes()).hexdigest())\nraise SystemExit(result)\nPY", + "source_before_sha256": "2cc1ffae363bc7334d5e50fdc088b858ab60a28130cde20fa581690088459aa5", + "source_after_sha256": "2cc1ffae363bc7334d5e50fdc088b858ab60a28130cde20fa581690088459aa5", + "output_file": "scratch/review/round-9-mutation-apply_unknown_alternate_refusal_to_fully.txt" + } + ], + "round_9_note": "Three isolated in-memory implementation mutations were caught and discarded against the final source. Restoring the positive DISABILITY return for UNKNOWN establishment fails the reviewed status table; dropping UNKNOWN establishment from the covered-date bound fails the one-quarter-after-onset refusal; applying the alternate refusal to UNKNOWN FULLY fails its favorable ordinary-witness test. Every foreground process checked the same source SHA-256 before and after. No implementation mutation was written to disk and no existing assertion was weakened.", + "round_9_final_source_sha256": "2cc1ffae363bc7334d5e50fdc088b858ab60a28130cde20fa581690088459aa5" } diff --git a/src/populace_dynamics/track_b/insured_status.py b/src/populace_dynamics/track_b/insured_status.py index 32e0f3645..54eb74496 100644 --- a/src/populace_dynamics/track_b/insured_status.py +++ b/src/populace_dynamics/track_b/insured_status.py @@ -14,7 +14,10 @@ The alternate test's 20/40 exclusion uses only quarters beginning before the FRA month, whether or not a period is declared established. For an established period, the witness quarter must also begin by the declared -end, known continuity date, or onset when neither date is known. Where +end, known continuity date, or onset when neither date is known. UNKNOWN +establishment before FRA uses onset too: an established completion can end +before a later DISABILITY witness. FULLY and CURRENTLY retain favorable +disregard of the period. Declared absence keeps the ordinary result. Where the literal and period-covered readings of RS00301.480 A differ, the alternate route retains its named refusal. Dated continuity restricts possible endings without establishing an end; @@ -723,6 +726,16 @@ def _coverage_checks(person, years, month, credits): ) +def _current_period_establishment_unknown(person): + """Whether a missing establishment fact admits a pre-FRA completion.""" + return ( + person.disability_onset is not None + and person.disability_onset < _fra_date(person).replace(day=1) + and person.current_disability_period_provenance + is EarningsProvenance.UNKNOWN + ) + + def _observable_coverage_paths( person, years, month, exit_month, kind, lo, quarter, upper, lower ): @@ -740,10 +753,12 @@ def _observable_coverage_paths( path from onset and earnings; its application facts remain unmodeled. """ # A successful witness at or after FRA cannot resolve an earlier - # alternate route requiring a freeze or DIB month before FRA. + # alternate route requiring a freeze or DIB month before FRA. UNKNOWN + # establishment also admits a period ending before a later witness. if lo[0] and ( kind is not InsuredTest.DISABILITY or quarter < _fra_date(person).replace(day=1) + and not _current_period_establishment_unknown(person) ): return if kind is InsuredTest.FULLY: @@ -820,8 +835,13 @@ def _pre1956_alternate_possible( # A witness must allow a freeze or DIB before FRA (Act 216(i)(2)(D), # 404.315(a), 404.321(a)-(b)), regardless of declared establishment. last = min(month, _fra_date(person).replace(day=1) - timedelta(days=1)) - if person.current_disability_period_established: + if ( + person.current_disability_period_established + or _current_period_establishment_unknown(person) + ): # 404.321(b): a pre-1980 period ends after disability ended or at 65. + # UNKNOWN establishment admits an early end and cannot supply + # either an end or continuity date, so only onset is shared. last = min( last, person.current_disability_period_end @@ -1609,6 +1629,10 @@ def insured_status( quarter beginning before the FRA month, independently of establishment. For established periods it must also begin by every completion's covered date: the declared end, continuity date, or otherwise onset. + UNKNOWN establishment before FRA uses onset for the same bound and + cannot bypass the alternate with a later positive DISABILITY witness. + FULLY and CURRENTLY retain true favorable-disregard witnesses; declared + absence and onset at or after FRA admit no established completion. Disagreement with the literal any-quarter reading retains the named alternate refusal; post-1980 endings can differ under 404.321(c). Establishment is an input error only if no ordinary, observable, or @@ -1638,12 +1662,7 @@ def insured_status( person.prior_disability_periods_provenance is EarningsProvenance.UNKNOWN ) - current_unknown = ( - person.disability_onset is not None - and person.disability_onset < _fra_date(person).replace(day=1) - and person.current_disability_period_provenance - is EarningsProvenance.UNKNOWN - ) + current_unknown = _current_period_establishment_unknown(person) end_unknown = _period_end_unknown(person, month) max_rows, _ = _world( person, diff --git a/tests/README-tiers.md b/tests/README-tiers.md index 07e25fc36..7ad540d42 100644 --- a/tests/README-tiers.md +++ b/tests/README-tiers.md @@ -39,9 +39,9 @@ pytest --collect-only -q -m oracle_policyengine | tail -1 | Tier | Tests at HEAD | |---|---:| -| `unit` | 20,678 | +| `unit` | 20,695 | | `artifact` | 4,271 | | `integration_psid` | 1,471 | | `reproduction_legacy` | 520 | | `oracle_policyengine` | 308 | -| **Total** | **27,248** | +| **Total** | **27,265** | diff --git a/tests/test_track_b_insured_status_fix_round_7.py b/tests/test_track_b_insured_status_fix_round_7.py index 7fcfff994..080e97346 100644 --- a/tests/test_track_b_insured_status_fix_round_7.py +++ b/tests/test_track_b_insured_status_fix_round_7.py @@ -158,17 +158,24 @@ def test_unestablished_period_keeps_alternate_after_fra( _assert_row(row, i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956) -@pytest.mark.parametrize("state", ["none", "unknown"]) -def test_unestablished_period_pre_fra_neighbour_keeps_ordinary_result(state): +def test_unestablished_period_pre_fra_neighbour_keeps_ordinary_result(): person, years = _case(fra_month=5) row = _row( - _unestablished(person, state), years, test=i.InsuredTest.DISABILITY + _unestablished(person, "none"), years, test=i.InsuredTest.DISABILITY ) _assert_row(row) assert row.result.disability.insured assert row.result.disability.qualifying_quarter == date(1960, 4, 1) +def test_unknown_establishment_pre_fra_neighbour_keeps_alternate_refusal(): + person, years = _case(fra_month=5) + row = _row( + _unestablished(person, "unknown"), years, test=i.InsuredTest.DISABILITY + ) + _assert_row(row, i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956) + + @settings(max_examples=16, deadline=None) @example(fra_month=1, witness_year=1960, witness_quarter=1) @example(fra_month=2, witness_year=1960, witness_quarter=1) diff --git a/tests/test_track_b_insured_status_fix_round_9.py b/tests/test_track_b_insured_status_fix_round_9.py new file mode 100644 index 000000000..44bfd72f1 --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_9.py @@ -0,0 +1,265 @@ +"""Statutory conformance: UNKNOWN establishment covers every completion. + +Invented declarations only. No population, behavioral, payment, or forecast +claim. Public evaluator rows retain each refusal and its exact weight. +""" + +import calendar +from dataclasses import replace +from datetime import date, timedelta +from fractions import Fraction + +import pytest +from hypothesis import example, given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as i +from populace_dynamics.track_b.gross_benefits import count_family_outcomes +from tests.test_track_b_insured_status import history +from tests.test_track_b_insured_status_fix_round_6_routes import ( + _ordinary_pre1956_case, +) +from tests.test_track_b_insured_status_fix_round_7 import _case + +OBSERVED = i.EarningsProvenance.OBSERVED +UNKNOWN = i.EarningsProvenance.UNKNOWN +QUERY = date(1968, 1, 1) +WEIGHT = Fraction(7, 3) +ALTERNATE = i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956 + + +def _declaration(person, established): + return replace( + person, + current_disability_period_established=established, + current_disability_period_provenance=( + UNKNOWN if established is None else OBSERVED + ), + current_disability_period_end=None, + current_disability_period_end_provenance=UNKNOWN, + current_disability_period_continues_through=None, + current_disability_period_continues_through_provenance=UNKNOWN, + ) + + +def _row(person, years, *, test=i.InsuredTest.DISABILITY): + return i.evaluate_insured_status( + "round-nine-unknown-establishment", + WEIGHT, + lambda: i.insured_status(person, years, QUERY, test=test), + ) + + +def _assert_row(row, reason=None): + counts = count_family_outcomes((row,)) + assert counts.rows == 1 + assert counts.weight == WEIGHT + if reason is None: + assert row.unsupported is None + assert row.result is not None + assert counts.unsupported_rows == 0 + assert counts.unsupported_weight == 0 + else: + assert row.result is None + assert row.unsupported.reason is reason + assert counts.unsupported_rows == 1 + assert counts.unsupported_weight == WEIGHT + + +@pytest.mark.parametrize( + "established", [None, False], ids=["unknown", "absent"] +) +@pytest.mark.parametrize("test", list(i.InsuredTest)) +def test_reviewed_status_table_retains_rows_and_weights(established, test): + person, years = _case(fra_month=5) + row = _row(_declaration(person, established), years, test=test) + reason = None + if established is None: + if test is i.InsuredTest.DISABILITY: + reason = ALTERNATE + elif test in (i.InsuredTest.CURRENTLY, i.InsuredTest.ALL): + reason = i.InsuredUnsupportedReason.UNKNOWN_CURRENT_PERIOD + _assert_row(row, reason) + if reason is None: + for kind, expected in ( + (i.InsuredTest.FULLY, True), + (i.InsuredTest.CURRENTLY, False), + (i.InsuredTest.DISABILITY, True), + ): + if test in (i.InsuredTest.ALL, kind): + assert getattr(row.result, kind.value).insured is expected + + +def test_unknown_fully_keeps_favorable_ordinary_witness(): + # An established completion cannot take away favorable disregard. + person, years = _case(fra_month=5) + row = _row(_declaration(person, None), years, test=i.InsuredTest.FULLY) + _assert_row(row) + assert row.result.fully.insured + + +def _onset_case(*, later_quarter=False, witness_year=1955, witness_quarter=2): + person, years, _ = _ordinary_pre1956_case() + if later_quarter: + years[1950] = i.CoverageYear( + OBSERVED, qc_quarters=(False, True, True, True) + ) + years[1940] = i.CoverageYear(OBSERVED, qc_quarters=(True,) * 4) + years[witness_year] = i.CoverageYear( + OBSERVED, + qc_quarters=tuple(q == witness_quarter for q in range(1, 5)), + ) + return _declaration(person, None), years + + +def test_unknown_establishment_keeps_round_five_onset_quarter_witness(): + person, years = _onset_case() + row = _row(person, years) + _assert_row(row) + assert row.result.disability.insured + assert row.result.disability.qualifying_quarter == date(1955, 1, 1) + + +def test_unknown_establishment_refuses_witness_one_quarter_after_onset(): + person, years = _onset_case(later_quarter=True) + _assert_row(_row(person, years), ALTERNATE) + + +def test_unknown_establishment_post1955_onset_keeps_ordinary_status(): + person, years = _onset_case() + person = replace(person, disability_onset=date(1956, 1, 15)) + row = _row(person, years) + _assert_row(row) + assert row.result.disability.insured + + +@pytest.mark.parametrize("days_after_fra", [0, 14]) +def test_unknown_establishment_at_or_after_fra_keeps_existing_refusal( + days_after_fra, +): + person, years = _case(fra_month=5) + person = replace( + _declaration(person, None), + birth_date=date(1890, 7, 2), + disability_onset=date(1955, 7, 1) + timedelta(days=days_after_fra), + ) + _assert_row(_row(person, years), ALTERNATE) + + +def _completion(person, end): + return replace( + _declaration(person, True), + current_disability_period_end=end, + current_disability_period_end_provenance=( + UNKNOWN if end is None else OBSERVED + ), + ) + + +@settings(max_examples=6, deadline=None) +@example(witness_year=1955, witness_quarter=2) +@given( + witness_year=st.sampled_from([1955, 1956]), + witness_quarter=st.integers(2, 4), +) +def test_unknown_establishment_cannot_compute_when_completion_refuses( + witness_year, witness_quarter +): + person, years = _onset_case( + later_quarter=True, + witness_year=witness_year, + witness_quarter=witness_quarter, + ) + # Both endings are valid through the alternate route. The ordinary + # witness occurs after the earliest possible declared ending. + completions = [ + _row(_completion(person, end), years) + for end in (date(1955, 1, 31), None) + ] + assert any( + row.unsupported is not None and row.unsupported.reason is ALTERNATE + for row in completions + ) + for row in completions: + _assert_row(row, ALTERNATE) + covered = _row(_completion(person, date(1956, 12, 31)), years) + _assert_row(covered) + assert covered.result.disability.insured + unknown = _row(person, years) + _assert_row(unknown, ALTERNATE) + assert unknown.result is None + + +@settings(max_examples=6, deadline=None) +@given(ending_month=st.integers(1, 12)) +def test_unknown_establishment_keeps_agreed_completion_status(ending_month): + person, years = _onset_case() + end = date(1955, ending_month, calendar.monthrange(1955, ending_month)[1]) + # The onset-quarter witness lies within every possible established + # completion, including the unobserved-ending declaration. + completed = [ + _row(_completion(person, ending), years) for ending in (end, None) + ] + absent = _row(_declaration(person, False), years) + for row in (*completed, absent): + _assert_row(row) + assert row.result.disability.insured + unknown = _row(person, years) + _assert_row(unknown) + assert unknown.result.disability.insured + + +def _date_oracle_case(witness, fra_month): + person = i.Person( + date(1895, fra_month, 2), + sex=i.Sex.FEMALE, + disability_onset=date(1955, 7, 15), + current_disability_period_established=None, + current_disability_period_provenance=UNKNOWN, + prior_disability_periods_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + years = history(person, QUERY, {year: 4 for year in range(1951, 1955)}) + years[1940] = i.CoverageYear(OBSERVED, qc_quarters=(True,) * 4) + years[1950] = i.CoverageYear( + OBSERVED, qc_quarters=(False, False, False, True) + ) + years[1955] = i.CoverageYear( + OBSERVED, qc_quarters=(True, True, False, False) + ) + flags = list(years[witness.year].qc_quarters) + flags[(witness.month - 1) // 3] = True + years[witness.year] = i.CoverageYear(OBSERVED, qc_quarters=tuple(flags)) + return person, years + + +@settings(max_examples=12, deadline=None) +@example(witness_year=1955, witness_quarter=3, fra_month=5) +@example(witness_year=1955, witness_quarter=4, fra_month=5) +@example(witness_year=1960, witness_quarter=2, fra_month=5) +@example(witness_year=1960, witness_quarter=4, fra_month=12) +@given( + witness_year=st.sampled_from([1955, 1956, 1959, 1960]), + witness_quarter=st.integers(3, 4), + fra_month=st.integers(1, 12), +) +def test_independent_date_oracle_classifies_unknown_establishment_both_ways( + witness_year, witness_quarter, fra_month +): + # Plain dates determine the expectation. No production date, coverage, + # alternate-route, or disability-witness helper supplies the oracle. + onset = date(1955, 7, 15) + witness = date(witness_year, (witness_quarter - 1) * 3 + 1, 1) + excludes_alternate = ( + witness <= onset + and witness < date(1960, fra_month, 1) + and witness < date(1960, 10, 1) + ) + person, years = _date_oracle_case(witness, fra_month) + row = _row(person, years) + _assert_row(row, None if excludes_alternate else ALTERNATE) + assert (row.result is not None) is excludes_alternate + assert (row.unsupported is not None) is (not excludes_alternate) + if excludes_alternate: + assert row.result.disability.insured diff --git a/tests/tier_counts.json b/tests/tier_counts.json index 7faef98f1..41c3889b6 100644 --- a/tests/tier_counts.json +++ b/tests/tier_counts.json @@ -1,7 +1,7 @@ { "schema_version": 1, "counts": { - "unit": 20678, + "unit": 20695, "artifact": 4271, "integration_psid": 1471, "reproduction_legacy": 520, From 281cfb4b336eb1638542e3c3a0c2f5a80d3621ae Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sat, 31 Oct 2026 15:33:38 -0400 Subject: [PATCH 15/46] Respect recovery quarters and prove insured establishment first (#562 round 10) Three review findings, plus one interface case I added. 20 CFR 404.321(b) ends a period of disability on the last day of the second month after the month disability ended, so a historical declared end falls two months after recovery. The code treated the end as the last disabled date. It now infers a recovery month only where paragraph (b) governs: not from February 1981 on, and not for an end at the FRA or death month. A recovery month before onset is invalid, and an insured start can't follow the recovery month. The pre-1956 alternate scan stops two months earlier, never before onset, and it also does so for FRA and death endings, because a recovery completion stays possible there. Validity takes the latest bound and exclusion the earliest, so the rule refuses by name where they differ. The alternate continuous-QC clock now tries both RS 00301.132 treatments: every prior period used, or every prior period disregarded. Inside-period quarters leave the clock unless they are credited endpoints. Establishment now runs a conservative minimum-QC proof before enumeration, so 15 lifetime QCs fail as invalid input instead of hitting the complexity refusal when every route needs 20. Blindness and UNKNOWN prior history skip the proof. Declared foreign credits above the six-QC floor now refuse by name, which keeps the unmodeled route from reading as impossible. This makes no claim about totalized eligibility. One earlier test held six own QCs with foreign credits as invalid; it now uses three, and a new test pins the six-QC refusal. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 331 +++++++++---- .../track_b_insured_status_mutations.json | 377 +++++++++++++- .../track_b/insured_status.py | 190 ++++++-- tests/README-tiers.md | 4 +- ...est_track_b_insured_status_fix_round_10.py | 460 ++++++++++++++++++ ...ack_b_insured_status_fix_round_10_proof.py | 244 ++++++++++ ...b_insured_status_fix_round_3_validation.py | 4 +- ..._insured_status_fix_round_5_possibility.py | 12 +- ...k_b_insured_status_fix_round_6_ordering.py | 13 +- ...ack_b_insured_status_fix_round_6_routes.py | 4 +- ...test_track_b_insured_status_fix_round_7.py | 31 +- ...test_track_b_insured_status_fix_round_8.py | 18 +- ...test_track_b_insured_status_fix_round_9.py | 4 +- tests/test_track_b_insured_status_sources.py | 12 + tests/tier_counts.json | 2 +- 15 files changed, 1547 insertions(+), 159 deletions(-) create mode 100644 tests/test_track_b_insured_status_fix_round_10.py create mode 100644 tests/test_track_b_insured_status_fix_round_10_proof.py diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index a024adb3f..a879a5952 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -97,8 +97,9 @@ explicitly means no established periods. The default provenance is `disability_onset` supplies the ordinary continuous-disability premise from that day through the query month; the rule does not adjudicate recovery. -A declared historical period end or an UNKNOWN establishment completion -can limit the alternate-pre1956 scan, as required by 404.321(b) below. Onset may +A declared historical period end can imply a recovery month under +404.321(b), and an UNKNOWN establishment completion can limit the +alternate-pre1956 scan as described below. Onset may be later within the query month, but not in a later month. Onset alone never establishes a period or freezes elapsed years. With an onset, the caller must explicitly declare `current_disability_period_provenance` and @@ -122,37 +123,69 @@ across the ordinary route, automatically observable specialist routes, and declared `CoverageCondition` routes. An unresolved specialist possibility retains its named refusal. The automatically observable alternate-pre1956 scan independently obeys the same immutable start -horizon: an ending or continuity observation before July 1952 cannot be -rescued by its first permitted July 1, 1952 start (RS .480 B.1). Explicit -specialist declarations remain separately preserved. RS .480 A also makes -that automatic alternate unavailable if even the lower-credit filling has -20/40 in a disabled quarter before October 1960. The test uses the ordinary -disability window, including favorable use or disregard of all prior -periods, from onset through the earliest of the query, 1960Q3, and the -quarter containing the last day of the month before FRA. For an established -current period it also stops at the declared end, or, with an UNKNOWN end, -the continuity date if supplied and otherwise onset. These are the dates -through which every ending completion still covers the period. For UNKNOWN -establishment before FRA, an established completion may end in the onset -quarter. The schema permits neither an end nor a continuity date without -establishment, so onset supplies the same covered-date bound. Declared -absence has no established completions and keeps its ordinary result. -The FRA bound applies regardless of whether a period is declared established: the -witness must support a freeze or DIB (Act 216(i)(2)(D); 404.315(a); -404.321(a)–(b)). A quarter beginning before the FRA month remains eligible -when FRA falls in its second or third month. A witness in the quarter -containing the covered date remains eligible because that quarter begins -on or before it; a witness in the next quarter does not exclude the route. +horizon. The first permitted alternate start is July 1, 1952 (RS .480 B.1). +An earlier fixed start horizon cannot be rescued by that later witness. +Explicit specialist declarations remain separately preserved. + The captured 404.321(b), headed "When disability ended before December 1, -1980", governs this scan's era and says: +1980", says: > Your period of disability ends on the last day of the month before the month in which you become 65 years old or, if earlier, the last day of the second month following the month in which your disability ended. -An earlier declared end in this era therefore reflects an ended disability; -it cannot be treated as an administrative fact independent of recovery. -Section 404.321(c) supplies different endings when disability ends after -November 1980. This note makes no claim about those endings beyond the -implemented date declarations and candidate evaluation. +A declared end that can only be a recovery ending therefore implies that +disability ended two calendar months earlier. The helper returns that +recovery month only for an end before February 1981, before the month +preceding FRA, and before the month of death. January 31, 1981 is the last +ending to which this inference can apply: disability ending after November +1980 instead falls under paragraph (c), and February 1981 is the first +month an ending under that paragraph can reach. An end in the month before +FRA or later may be the FRA ending; an end in the death month or later may +be the death ending. Neither implies a recovery month. The rule infers no +recovery month for paragraph (c) endings and makes no claim about how those +endings are determined. + +Validity asks for the latest date at which any route could hold. A recovery +month before the onset month is an input error. If the helper returns a +recovery month, that month caps the insured-start horizon and a derived +start after it is invalid. A quarter beginning in or before that month can +still count because the worker was disabled in that quarter +(404.320(b)(2); 404.131(a)). The calendar end alone does not make either of +the following two grace months a disabled starting quarter. FRA and death +endings keep their existing validity bound, because they do not imply a +recovery date. Continuity, query, death, and FRA retain their separate caps. + +Alternate-route exclusion asks the opposite question: through what date +was the worker disabled in every completion? RS .480 A makes the automatic +alternate unavailable if even the lower-credit filling has 20/40 in a +shared disabled quarter before October 1960. The ordinary 40-quarter +window uses favorable use or disregard of all prior periods. For an +established period, the shared date is the declared end minus two months, +or, with an UNKNOWN end, the continuity date minus two months; without +either fact it is onset. It is never earlier than onset. Month subtraction +uses the calendar index `year * 12 + month - 1 - 2`. +This conservative exclusion bound also applies to FRA and death endings: +a recovery two months before such an ending remains a possible completion, +although the declaration does not imply that recovery occurred. UNKNOWN +establishment before FRA has neither an end nor a continuity declaration, +so its shared date is onset. Declared absence keeps its ordinary result. +The scan also stops at the query, 1960Q3, and the quarter containing the +last day of the month before FRA, for every person (Act 216(i)(2)(D); +404.315(a); 404.321(a)–(b)). A quarter remains eligible exactly when its +first month is on or before the shared date and before the FRA month. +These latest-validity and earliest-exclusion bounds deliberately go in +opposite directions: an input error excludes every possible route, while +a computed UNKNOWN result must survive every completion. + +The alternate's continuous-QC clock also considers both use of every prior +period and disregard of every prior period. RS .132 B.2 excludes a quarter +all or part of which is in a used disability period, except a beginning or +ending quarter that is a QC, from the "period of continuous QCs under the +alternate insured status provision". C.2 requires all prior periods to be +used or all disregarded. The shared world, boundary-assignment, and credit +assignment helpers implement both treatments. The remaining clock must +contain at least six quarters, each credited, and at least 20 total QCs +must remain assignable (RS .480 A). A missing QC outside an excluded period +breaks continuity; an uncredited interior quarter of a used period does not. RS .480 A permits two readings. Its "any quarter before 10/60" supports the literal scan, while "though under a disability" and "for freeze or DIB" @@ -165,12 +198,12 @@ a universal exclusion of that route for DISABILITY. If some feasible fillings still lack 20/40, application facts remain absent and the alternate possibility retains its refusal. On the ordinary route, a valid -filling must supply one insured start that is at or before the declared -administrative end and clears every prior-period overlap. A later witness -at the query cannot rescue an immutable earlier end. The scan therefore -stops at that end, any continuity observation, death, or FRA cap, whichever -is earlier. Maximum credits decide the monotone insured-by-that-date -question. If that representative's derived start overlaps a prior period, +filling must supply one insured start that is at or before the applicable +recovery or administrative-end bound and clears every prior-period overlap. +A later witness at the query cannot rescue an immutable earlier bound. The +scan therefore stops at that bound, any continuity observation, death, or +FRA cap, whichever is earlier. Maximum credits decide the monotone +insured-by-that-date question. If that representative's derived start overlaps a prior period, the rule checks lower-credit fillings and, when needed, enumerates the bounded concrete fillings for a single valid period. It never combines the end compliance of one filling with the overlap compliance of another. @@ -188,6 +221,40 @@ transitional, military, railroad, or other specialist routes. A flag or observable specialist route that could validate the declaration prevents that input error and preserves a refusal row. +After the fixed-quarter overlap check, establishment validation considers +flagged specialist routes, the six-QC floor, declared totalization credits, +and then a minimum-requirement proof before invoking any alternate scan, +boundary enumeration, or UNKNOWN-prior-history feasibility scan. The proof +runs only with known prior history and without statutory blindness. Every +remaining ordinary 20/40 or alternate route needs 20 QCs. If the earliest +candidate start permits the under-31 or subsequent-special rule, the proof +also takes that rule's requirement after removing every prior-period +quarter from elapsed time, including otherwise credited endpoints. This +gives no more elapsed quarters than any actual witness. The special +requirement never decreases as elapsed time rises, so the minimum of these +requirements cannot exceed the true requirement of any remaining route. +If maximum feasible lifetime QCs falls below that minimum, no filling can +establish the period. Fully insured prerequisites and actual credit-window +availability can only add constraints; omitting them cannot make this +lower bound too high (404.130(a)–(f); RS .480 A). + +Blindness uses the fully insured prerequisite alone (`blindness_fully_only`), +so its proof stops at the six-QC floor. UNKNOWN prior history can supply +additional exclusions and disables the stronger minimum-requirement proof. +Declared totalization credits likewise preserve an unmodeled route after +the six-QC floor, allowing `totalization_credits_unsupported` to be raised +with its evaluator row. The rule claims nothing about how a totalized +route works; no captured totalization provision is used to infer foreign +credit requirements or benefits. The existing fewer-than-six-QC input +error remains part of the declared supported-credit contract. + +An older validation-order fixture supplied six own QCs plus declared foreign +credits and expected an input error after ordinary prerequisites failed. +The unmodeled foreign route now prevents that conclusion. The fixture uses +three own QCs to keep its validation-order purpose, and a public evaluator +regression retains the original six-QC case as a named totalization refusal. +This changes no substantive claim about totalized eligibility. + When prior periods are UNKNOWN, favorable disregard of every period can still decide the Boolean status even if the current period's derived start is uncertain. `current_disability_period_start` is then `None`, and @@ -250,8 +317,14 @@ end, never its actual date; an UNKNOWN end stays in `unknown_facts` at and after FRA, including when prior history is also UNKNOWN. Both missing facts remain disclosed; UNKNOWN prior history uses the broader universal envelopes rather than inventing a concrete current period for enumeration. -A supplied date retains the existing declaration semantics; -known ending provenance requires that date. +The `_current_period_completions` enumeration deliberately over-includes +some early UNKNOWN endings that the recovery-month reading would reject +if declared concretely. That widens the set whose requested results must +agree. It can preserve an extra refusal or widen a count envelope, but a +returned status that agrees on the larger set still agrees on every valid +completion. The enumeration is therefore left unchanged. A supplied date +retains the existing declaration semantics; known ending provenance +requires that date. An observed running period instead uses `current_disability_period_continues_through: date | None`, with @@ -465,8 +538,11 @@ configuration receives `ongoing_disability_period_dli_horizon_unsupported`. For prior disability periods, only years containing their endpoint quarters need assignment enumeration. Other annual credits maximize overlap directly. The calculation considers all-used and all-disregarded contexts, never a -selectively chosen subset. More than 4,096 boundary combinations receive an -explicit computational-coverage refusal. No approximate search is used. +selectively chosen subset, including the alternate continuous-QC clock +(RS .132 B.2, C.2). More than 4,096 boundary combinations receive an explicit +computational-coverage refusal only after every applicable fixed-overlap, +six-QC, and minimum-requirement impossibility proof. No approximate search +is used. For example, a man born February 2, 1900 queried in December 1974 with 20 QCs from 1969–1973 needs 14 QCs under the retirement fully insured rule, @@ -484,9 +560,15 @@ Input errors are raised before any of these coverage decisions. The enum is a subclass of the shared `FamilyConfigurationUnsupported`. The refusal order starts with full schema and history validation, including -every raw row. The establishment possibility proof then precedes coverage -refusals. Before that proof, raw conversion can encounter only four -reachable refusals: `qc_amount_year_unsupported`, +every raw row. The establishment possibility checks then precede coverage +refusals. Within those checks, fixed-quarter overlap comes first, followed +by flagged specialist possibilities, the six-QC floor, declared foreign +credits, the known-history nonblind minimum-requirement proof, and the +automatic alternate route. Only then can boundary assignments, UNKNOWN +prior-history feasibility, or concrete earnings fillings be enumerated. +Neither `_unknown_prior_history_is_empty` nor an alternate-path +`_boundary_variants` call can run ahead of the applicable proof. Before +that proof, raw conversion can encounter only four reachable refusals: `qc_amount_year_unsupported`, `1937_earnings_allocation_unsupported`, `pre1955_agricultural_allocation_unsupported`, and `pre1951_self_employment_unsupported`. These are deferred while possibility @@ -498,7 +580,8 @@ reason, the existing specialist, date, applicability, and requested-status checks follow. In the requested-status checks, a positive ordinary DISABILITY witness does not bypass the observable alternate route when current establishment is UNKNOWN and onset precedes the FRA month. Its -20/40 exclusion must hold even for a completion ending in the onset quarter. +20/40 exclusion must hold even for the earliest recovery completion +consistent with the declaration. FULLY and CURRENTLY keep favorable-disregard true results; a false CURRENTLY result can still refuse for unknown establishment before ALL reaches DISABILITY. No established completion exists for onset in or after the FRA @@ -517,7 +600,7 @@ input. An input error propagates and creates no row. | Unknown section 214(c) applicability may change a requested status | `sspa211_applicability_unknown` | | Standalone requirement helper needs coverage history to derive a declared current period start | `current_disability_period_requires_history` | | Ongoing established current period, known prior-period history, and a frozen-exit DLI horizon beyond query | `ongoing_disability_period_dli_horizon_unsupported` | -| Any foreign totalization credits | `totalization_credits_unsupported` | +| Any foreign totalization credits after the shared chronology and six-QC checks; the route itself remains unmodeled | `totalization_credits_unsupported` | | Declared deemed nonprofit/veteran fully insured path | `deemed_fully_insured_unsupported` | | Declared transitional insured path | `transitional_insured_unsupported` | | Known section 214(c) applicability needs unimplemented work-authorization/visa adjudication, including never-assigned alien SSNs | `alien_worker_sspa211_unsupported` | @@ -531,7 +614,7 @@ input. An input error propagates and creates no row. | Pre1951 self-employment income | `pre1951_self_employment_unsupported` | | Earnings require an increment after 2027 | `qc_amount_year_unsupported` | | Query before 1968; blind query before 1973; subsequent-special query before May 1983 | `entitlement_before_1968_unsupported`, `blindness_before_1973_unsupported`, `subsequent_special_before_1983_unsupported` | -| More than 4,096 disability-boundary combinations, or unresolved ordinary-establishment overlap requiring more than 4,096 credit fillings after the candidate-quarter exclusion check | `disability_boundary_assignments_unsupported` | +| More than 4,096 disability-boundary combinations, or unresolved ordinary-establishment overlap requiring more than 4,096 credit fillings, after the applicable fixed-quarter, six-QC, and minimum-requirement proofs | `disability_boundary_assignments_unsupported` | The round-3 observable-trigger audit covers every `CoverageCondition`. An explicit condition continues to refuse independently of its ordinary @@ -552,7 +635,7 @@ allocation or adjudicate application facts. | Condition | Observable trigger or absent fact | | --- | --- | | `SIMPLIFIED_PRE1951` | Raw 1937–1950 quarterly wages provide an aggregate divided by $400; post1950 upper QCs and the fully insured prerequisite bound whether it could decide status (213(c); 404.110(d); RS .315). UNKNOWN pre1951 years can supply unbounded raw wages and therefore also trigger the refusal. Direct `qc_quarters` declare credited quarters rather than raw wages. The simplified method does not apply to a disability claim. Filing, retroactivity, and section 227 facts remain unmodeled. | -| `DISABILITY_BEFORE_1956` | Medical onset and QCs reveal a possible RS .480 alternative: at least 20 total QCs and every quarter from 1951Q1 through the quarter before a qualifying 1952Q3–1955Q4 candidate quarter at or after onset, with at least six such quarters. For declared current establishment, that candidate must fit the immutable declared-end/continuity/death/FRA horizon. RS .480 A excludes the route when the lower-credit filling has 20/40 in the rule's disabled-quarter scan before October 1960; if only some fillings do, the alternate remains possible. Refuse automatically when this could change a failed disability predicate. Application conditions remain unmodeled. | +| `DISABILITY_BEFORE_1956` | Medical onset and QCs reveal a possible RS .480 alternative: at least 20 total QCs and every counted quarter from 1951Q1 through the quarter before a qualifying 1952Q3–1955Q4 candidate quarter at or after onset, with at least six such quarters, under favorable all-period use or disregard (RS .132 B.2, C.2). For declared current establishment, that candidate must fit the immutable declared-end/continuity/death/FRA horizon. RS .480 A excludes the route when the lower-credit filling has 20/40 in the rule's disabled-quarter scan before October 1960; if only some fillings do, the alternate remains possible. Refuse automatically when this could change a failed disability predicate. Application conditions remain unmodeled. | | `DEEMED_FULLY_INSURED` | Wages and dates do not identify covered nonprofit employment or veteran status; retain the explicit flag (404.111–.112; RS .106/.107/.470). | | `TRANSITIONAL_INSURED` | Cohort dates alone do not identify the necessary historical benefit/application facts; retain the explicit flag (RS .101's transitional-benefit referrals). | | `RAILROAD_CREDITS`, `MILITARY_CREDITS` | Ordinary covered earnings do not identify railroad or military service and additional credits; retain explicit flags (RS .350; RS .120/.470). | @@ -632,13 +715,16 @@ to a statutory sentence that does not state it. | I5. A supplied `special_insured` prior period begins before the age-31 attainment quarter. | B404.130(d)(1): a prior period "began before age 31" and the worker "were only insured under paragraph (c)"; (c)(1) requires age 31 not yet attained. A216(i)(3)(B)(iii) expressly uses "before the quarter" of age 31. The flag declares this particular adjudicated young-worker route, not every possible special credit regime. | | I6. An alien worker's actual pre2004 SSN assignment conflicts with declared SSPA applicability; birth on/after January 1, 2004 conflicts with declared exemption. Both never-assigned and an assigned SSN, or assignment before birth, remain invalid. A worker born before 2004 may pair a post2003 assignment or never-assigned status with an adjudicated exemption. | RS .102 B.1 says an alien assigned an SSN before 2004 "is exempt", including a nonwork SSN. B.3.b says, "If an alien worker could have legitimately been assigned an SSN before 1/1/2004, the worker is exempt from the requirements of section 211 of the SSPA." Its wrong-number SS-5 scenario issued another person's number "instead of assigning the alien worker their own SSN". Thus observed or convention-filled exemption overrides either later-assignment or never-assigned presumptions when legitimate pre2004 assignment was possible. Birth on/after January 1, 2004 rules out that exception independently of the assignment record. B.4.b's worker without an SSN "is nevertheless considered to meet the work SSN requirement" when work-authorized; meeting that requirement alone supplies no exemption. | | I7. Explicit quarterly QCs or positive quarterly wages cannot occur before birth, after the query/coverage-end quarter, or after the death quarter. Every required coverage year is declared exactly once through the earliest query, exit, or death year. | A213(a)(2)(B)(i), (v): "no quarter after the quarter in which an individual dies" and "no quarter shall be counted ... prior to the beginning of such quarter"; B404.146(a)-(b) agree. Birth and supplied-record exit caps, complete years, and no implicit zeros are interface premises. Annual counts are capped rather than dated after exit. Specialist earned-basis or additional-credit declarations remain refusals and do not reinterpret an explicit ordinary covered-quarter declaration. | -| I8. A declared current establishment with no possible insured start is invalid only after the shared possibility check excludes every route and every feasible prior/earnings filling. One ordinary filling must satisfy the start, declared end, continuity, and overlap constraints together. | C320(b)(2) requires insured disability "in the calendar quarter in which you became disabled, or in a later calendar quarter"; C321(a) chooses the first such quarter. B404.130(a) says "four different rules"; RS .480 supplies an additional historical test with "at least 20 quarters of coverage" and every qualifying 1951 quarter, subject to its own 20/40 exclusion through the quarter containing the last day of the month before FRA, for every person (A216(i)(2)(D), C315(a), C321(a)–(b)). Independent flagged and automatic guards preserve available routes; the automatic pre1956 scan obeys the same immutable starting horizon. The ordinary scan is capped by the declared end and continuity date as well as query/death/FRA. Maximum credits decide whether insurance by that fixed date is possible. A failure caused by a derived prior-quarter overlap first checks whether any candidate starting quarter clears the supplied periods, then requires a lower-credit or enumerated filling with a nonoverlapping first start by the same cap. An ordinary or alternate starting witness after the declared end never supplies possibility. Nor can a later 20/40 witness establish impossibility on every reading of RS .480 A: C321(b) makes the earlier pre-FRA ending evidence that disability ended in this era. The named alternate refusal preserves that defensible route. For an UNKNOWN end, only a witness through the continuity date, or onset when continuity is absent, is shared by every ending completion. | -| I9. Fewer than six maximum feasible ordinary lifetime QCs proves current establishment impossible only when all specialist possibilities have already been excluded. | B404.110(b)(1): "You need at least 6 QCs but not more than 40 QCs"; B404.130(a): "you must be fully insured". B404.110(a) separately names deemed veteran/nonprofit routes, and RS .131/.350 cover other credits. Those alternatives prevent applying the ordinary six-QC input-error proof to a potentially valid specialist declaration. A record composed entirely of direct final QC declarations (`qc_count` or `qc_quarters`) and UNKNOWN years already fixes or bounds all admissible QCs, including RR credits, so the RR flag cannot add quarters beyond that envelope. This is the direct-credit input contract, not a claim that ordinary RSDI credits always exhaust freeze credits: RS .131 expressly allows credits "not creditable for other" purposes. If earnings allocation or that final-credit declaration is unresolved, the RR route remains possible; RS .230 and .350 supply annual and historical RR credit rules. Period exclusions alone cannot add ordinary QCs. | +| I8. A declared current establishment is invalid only after the shared possibility check excludes every route and every feasible prior/earnings filling. One ordinary filling must satisfy its insured start, recovery or administrative end, continuity, and overlap constraints together. | C320(b)(2) requires insured disability "in the calendar quarter in which you became disabled, or in a later calendar quarter"; C321(a) chooses the first such quarter. B404.130(a) supplies four ordinary rules and RS .480 supplies the alternate historical rule. The start horizon uses an inferred recovery month when I14 permits one, otherwise the declared end, together with continuity/query/death/FRA caps. Maximum credits establish only monotone insurance by that fixed horizon. A derived prior-quarter overlap requires a single lower-credit or enumerated filling whose first start also clears that overlap. An ordinary or alternate witness after the horizon cannot supply possibility. Flagged routes, the six-QC floor, declared totalization credits, and I15's minimum-requirement proof are considered before any alternate or boundary enumeration. The alternate's 20/40 exclusion instead uses U10's earliest date shared by every completion; a later witness cannot prove impossibility under every defensible reading of RS .480 A. | +| I9. Fewer than six maximum feasible ordinary lifetime QCs proves current establishment impossible after the independent flagged specialist possibilities have been excluded. | B404.110(b)(1): "You need at least 6 QCs but not more than 40 QCs"; B404.130(a): "you must be fully insured". B404.110(a) separately names deemed veteran/nonprofit routes, and RS .131/.350 cover other credits. Those alternatives prevent applying the ordinary six-QC input-error proof to a potentially valid specialist declaration. A record composed entirely of direct final QC declarations (`qc_count` or `qc_quarters`) and UNKNOWN years already fixes or bounds all admissible QCs, including RR credits, so the RR flag cannot add quarters beyond that envelope. This is the direct-credit input contract, not a claim that ordinary RSDI credits always exhaust freeze credits: RS .131 expressly allows credits "not creditable for other" purposes. If earnings allocation or that final-credit declaration is unresolved, the RR route remains possible; RS .230 and .350 supply annual and historical RR credit rules. Period exclusions alone cannot add ordinary QCs. The automatic alternate separately needs 20 QCs; the declared foreign-credit route is handled after this existing six-own-QC contract, without a substantive totalization claim (U11). | | I10. The supported calendar, mandatory historical sex, and explicit establishment declaration must be supplied: birth years 1870–9900, query years through 9990, sex for births before January 2, 1913, and establishment provenance whenever onset is present. | These are interface-domain requirements. B404.110(b)(2) and .132 apply different historical male/female endpoints; B404.110(c) excludes only a period "we established for you". Missing facts are not inferred. Calendar limits reserve space for date arithmetic and assert no legal incapacity outside the implementation domain; alternative credit routes cannot supply missing declared facts. | | I11. A continues-through observation requires established disability, cannot precede medical onset or the first feasible insured start, cannot exceed the pre-FRA or death boundary, and cannot follow a declared administrative end. | C320(b)(2) and C321(a) require the insured start; A216(i)(2)(D) and C321(c) bound the period's end. A declaration that a period was in force on a date requires that date to lie within one possible period. This is a dated observation, not an asserted ending; a date later than the query is allowed. Provenance and convention identifiers follow the existing fact schema. | | I12. A raw-credit conversion refusal cannot hide established-period impossibility that every feasible filling of that row preserves. | C320(b)(2), C321(a), and B404.110(b)(1) supply the insured-start and six-QC premises. The #530 input contract puts input errors before coverage refusals. Schema validation remains first; the four conversion refusals are deferred only for this proof, with unresolved rows bounded by feasible ordinary quarters. A surviving filling preserves the original refusal reason and note rather than manufacturing a supported status. | | I13. If no starting quarter from onset through the immutable horizon clears all supplied prior-period quarters, current establishment is impossible independently of credit fillings, their count, or a specialist route. | C320(b)(2) and C321(a) require an insured beginning within that interval; I4's nonoverlapping-quarter representation applies to that same beginning. A credit route cannot move a candidate outside the fixed interval or remove a supplied prior quarter. This fixed contradiction is checked before specialist possibility and filling enumeration; it does not treat UNKNOWN prior history as supplied empty history. | +| I14. A declared recovery-only historical end implies a recovery month two months earlier; recovery before the onset month or a derived start after that month is invalid. | C321(b) ends the period on "the last day of the second month following the month in which your disability ended". C320(b)(2) and B404.131(a) require an insured quarter in which the worker was disabled, so an administrative grace month cannot supply a new disabled quarter. The helper returns no recovery inference for an end on/after February 1, 1981, in/after the month preceding FRA, or in/after the death month. These carve-outs preserve the existing validity horizon and make no claim about paragraph (c) recovery or administrative ending rules. | +| I15. With known prior history, no blindness, no surviving flagged route, and no declared totalization credits, fewer maximum feasible lifetime QCs than the lowest remaining rule requirement proves establishment impossible before any coverage enumeration. | B404.130(b) needs 20 QCs; (c)–(d) permit the special half-elapsed-quarter rule with six-QC floor and 20-QC ceiling; RS .480 A also needs 20. At the earliest candidate start, remove every prior-period quarter from special elapsed time, including credited endpoints. Every actual use/disregard witness has at least those elapsed quarters, and later starts cannot reduce them. Taking the smallest applicable requirement therefore cannot exceed any true route minimum. Ignoring the fully insured prerequisite and window availability only relaxes the bound. Blindness (B404.130(e)) needs only fully insured status, and UNKNOWN prior history could remove further quarters; both disable the stronger proof. | + | ID and UNKNOWN collapse | Captured text and alternative-route defense | | --- | --- | | U1. UNKNOWN prior history can collapse to empty solely for impossibility validation when no earliest prior period could start insured, on/after birth, before current onset and the FRA end. | C320(b)(2) and C321(a) require an insured beginning without a still-earlier period. A216(i)(2)(A) permits "five full calendar months' duration or" DIB entitlement "for one or more months". The scan therefore admits a one-month period and maximum feasible earnings. Any possible ordinary or specialist starting route stops the proof. It establishes no observed empty-history fact. | @@ -646,29 +732,31 @@ to a statutory sentence that does not state it. | U3. With unknown prior/current periods, true ordinary FULLY and CURRENTLY status under favorable all-period disregard decides true. A DISABILITY witness must also survive any current-establishment completion that ends the disability before that witness. | C320(a): "If benefits ... would be denied or reduced because of a period of disability, the period of disability will not be taken into consideration." B404.130(f) also permits counting all prior quarters if favorable. RS .120 requires all periods used or all disregarded; selective exclusions are not assumed. Specialist credit regimes are refused first. | | U4. With unknown periods, fewer than six maximum feasible QCs decides false only on the ordinary route after specialist possibilities are excluded. | B404.110(b)(1) and B404.130(a) supply the six-QC prerequisite. U3's disregard cannot manufacture credits. Deemed, transitional, foreign, military/railroad, and automatically revealed historical alternatives retain named refusals instead of using this ordinary collapse. | | U5. UNKNOWN earnings decide a requested Boolean only if all lower/upper ordinary earnings witnesses agree, under the permitted fixed-period/all-period treatments; an uncertain established start refuses only after at least one feasible filling survives. | B404.143 credits one QC for each increment, maximum four; B404.130 and .146 supply assignment/exclusion rules. Adding ordinary QCs cannot invalidate a fixed treatment. A derived start cannot be silently held fixed when the completion changes it. If a lower or upper representative cannot construct the declared period, but another single filling meets its end, continuity, and prior-overlap constraints, the public result is `unknown_earnings_years_decide_status`. If no ordinary filling can qualify by the declared end and all independent routes are impossible, it is an input error and creates no row. A deferred raw-conversion row uses temporary unknown fillings only for possibility, then retains its conversion refusal. Specialist possibilities and administrative-end candidates are considered separately. | -| U6. UNKNOWN administrative end decides a status only when every end-quarter candidate from start through query/cap, plus permitted continuation, agrees, after applying any continuity lower bound. | A216(i)(2)(D) uses "whichever ... is the earlier"; C321(c)(3) includes "the last month for which you received benefits" after substantial gainful activity. Medical continuity cannot exclude early ends; a dated administrative continuity observation can. FRA/death caps limit the latest candidate and do not turn the unknown into a fact. Both ending and prior-history unknown facts remain disclosed when both are missing; UNKNOWN prior history uses the universal envelopes rather than inventing a derived current period to enumerate. An actual supplied end keeps its declared-date semantics; known ending provenance requires an ending date. | +| U6. UNKNOWN administrative end decides a status only when every end-quarter candidate from start through query/cap, plus permitted continuation, agrees, after applying any continuity lower bound. | A216(i)(2)(D) uses "whichever ... is the earlier"; C321(c)(3) includes "the last month for which you received benefits" after substantial gainful activity. Medical continuity cannot exclude early ends; a dated administrative continuity observation can. FRA/death caps limit the latest candidate and do not turn the unknown into a fact. Both ending and prior-history unknown facts remain disclosed when both are missing; UNKNOWN prior history uses the universal envelopes rather than inventing a derived current period to enumerate. The unchanged completion enumeration can include early endings rejected by I14 if declared concretely. Agreement across that larger set still implies agreement across every valid completion, while disagreement can preserve an extra refusal. An actual supplied end keeps its declared-date semantics; known ending provenance requires an ending date. | | U7. UNKNOWN SSPA applicability preserves an ordinary QC-only false status, but never a QC-only true status. | RS .102 B.2 says the worker "must meet one of the following additional requirements" and may fail "even if" the QC requirement is met. Applicability can remove ordinary insurance and cannot supply missing QCs. Known applicability retains adjudication refusal; any separate specialist path is refused first. | | U8. With UNKNOWN prior history, a known current period's start is certain onset only if the lower-credit favorable-disregard witness already insures at onset; otherwise the start stays unknown. | A216(i)(2)(C) and C321(a) make insured onset the earliest legal start. C320(a)'s disregard permits that witness, and no route can move this period before medical onset. Other potentially valid histories prevent an impossibility error but do not fabricate a start. | | U9. A continues-through observation removes only candidate administrative ends before its date; it never supplies an ending endpoint or removes UNKNOWN-end disclosure. | C321(c) enumerates actual ending events. Observation of a period still in force supplies a lower bound on those events, not their occurrence. Same-quarter ends remain possible, while a later-quarter observation makes the query quarter interior. | -| U10. An automatic alternate-pre1956 possibility can be removed for every filling only when the lower-credit filling already has ordinary 20/40 in a quarter covered by every ending completion, before October 1960. | RS .480 A makes the test available only to a disabled worker who "does not have 20/40 for freeze or DIB in any quarter before 10/60". Ordinary fixed-treatment recent-credit counts are monotone in added credits. The scan uses the ordinary 40-quarter window with favorable all-period use/disregard, from onset through the earliest of query, 1960Q3, and the quarter containing the last day of the month before FRA, for every person (A216(i)(2)(D), C315(a), C321(a)–(b)). A quarter stays eligible if FRA falls in its second or third month. It does not substitute the young-worker or blindness rule. For established current periods it additionally ends at the declared end, or the continuity date when the end is UNKNOWN, or onset when both are UNKNOWN. UNKNOWN establishment before the FRA month uses onset, because neither an end nor continuity can accompany that declaration and an established completion may end in the onset quarter. C321(b) governs pre-December-1980 endings; its earlier ending is tied to ended disability rather than an independent administrative event. RS .480 A's "any quarter" supports a literal wider scan, but "though under a disability" and "for freeze or DIB" support excluding post-period witnesses. Where they differ, retain the named alternate refusal. Only a lower-credit 20/40 witness shared by every period-ending completion excludes the alternate for every completion; an upper-only witness cannot do so. Application facts remain absent and are not inferred from this exclusion. The same guard is used for current-establishment and earliest-prior-history possibilities. | +| U10. An automatic alternate-pre1956 possibility can be removed for every filling only when the lower-credit filling has ordinary 20/40 in a quarter disabled in every ending completion, before October 1960. | RS .480 A says "does not have 20/40 for freeze or DIB in any quarter before 10/60". Counts under a fixed all-period use/disregard treatment are monotone in added QCs. The scan retains query, 1960Q3, and month-before-FRA caps for every person (A216(i)(2)(D); C315(a); C321(a)–(b)). For established current periods, its shared date is the declared end minus two calendar months, or continuity date minus two when the end is UNKNOWN, or onset if neither is supplied; it is never before onset. The same two-month exclusion offset applies to FRA/death endings because an earlier recovery remains a possible completion, without inferring that it occurred. UNKNOWN establishment before FRA uses onset. A quarter counts only if its first month is on or before that shared date. RS .480 A's "any quarter" supports a wider scan, while "though under a disability" and "for freeze or DIB" support the shared disabled-quarter scan. A difference preserves the named refusal. Young-worker or blindness witnesses are not substituted for 20/40, upper-only witnesses cannot exclude every filling, and application facts remain unmodeled. | + +| U11. Declared foreign totalization credits preserve an unmodeled establishment route after fixed chronology and the six-own-QC floor, and retain the named totalization refusal. | This is the existing declaration and coverage contract, not a claim derived from uncaptured totalization law. No 404.19xx provision is captured. The rule therefore does not infer totalized eligibility, foreign-credit minima, or benefit amounts, and cannot use the ordinary minimum-requirement proof to reject a ten-own-QC declaration with foreign credits. The existing fewer-than-six-own-QC controls remain input-invalid. | | ID and bound | Captured text and alternative-route defense | | --- | --- | | B1. UNKNOWN annual ordinary QCs range from zero through four, reduced by assignable birth/query/death/exit quarters. Deferred raw-conversion rows use their feasible minimum/maximum fillings only for establishment possibility. Exact annual amounts are monotone in earnings; every calendar year stays in 0–4. | B404.143: "we cannot credit you with more than four QCs for any calendar year"; A213(a)(2)(B)(vi) prohibits duplicate calendar-quarter QCs; B404.146 excludes unbegun/death quarters. Birth/exit are supplied-record premises. Additional-credit regimes retain refusal and cannot escape this bound through an ordinary result. Deferred rows still raise their original conversion refusal after a valid possibility survives; no temporary filling is exposed as a computed status. | | B2. Ordinary fully insured requirements lie in 6–40 and exclude only established disability years. Every elapsed-year endpoint uses its relevant candidate year and the historical sex/cohort rule. | B404.110(b)(1), (b)(2), (c), .132; A214(a) says "not counting ... any year any part of which was included in a period of disability". Medical onset without establishment cannot freeze years. Deemed/transitional alternatives are refused before using the ordinary requirement as universal. | | B3. A simplified-pre1951 possibility uses the smallest known freeze requirement, or six for unresolved establishment/history, and maximum post1950 ordinary credits without exclusions. UNKNOWN pre1951 raw wages remain potentially decisive. | A213(c) grants "one quarter of coverage for each $400" subject to resulting fully insured status; B404.110(c)-(d); RS .315 B.1-B.2 record alternate historical/application conditions. This is an over-approximation for refusal, not a computed deemed-credit answer. A favorable ordinary witness with a higher requirement cannot narrow it. | -| B4. An alternate-pre1956 possibility uses maximum feasible QCs and any eligible 1952Q3–1955Q4 quarter with at least 20 total QCs and every preceding 1951-onward quarter credited, minimum six, only if lower credits do not already establish 20/40 in its disabled-quarter scan before October 1960. Current establishment also requires the alternate quarter to fit every fixed starting bound. | RS .480 A requires "at least 20 quarters of coverage" and "all quarters beginning with 03/51 ... are QCs" with "at least six", and limits eligibility to workers without 20/40 before 10/60. B.1 gives first freeze day 07/01/52 and last 12/31/55. The first possible freeze day is July 1, 1952; an established current period already ended, or observed in force, before then cannot use a later automatic witness. The automatic scan shares the ordinary immutable end/continuity/death/FRA horizon. The exclusion ends no later than the quarter containing the last day of the month before FRA for every person, independently of established, absent, or UNKNOWN period status (A216(i)(2)(D), C315(a), C321(a)–(b)). An established current period further limits exclusion to the quarter containing the declared end; an UNKNOWN end limits it to the continuity date's quarter, or onset's quarter without continuity. These bounds preserve a named refusal when the literal any-quarter reading and the period-limited reading differ, and ensure that an UNKNOWN result holds for every declared-end completion. A successful ordinary DISABILITY witness beginning in or after the FRA month cannot bypass an otherwise possible alternate refusal. Pre-FRA ordinary witnesses retain their results when the applicable period-covered bound also permits exclusion. A lower-credit ordinary 20/40 witness removes the route for all fillings; an upper-only witness leaves it possible. Unmodeled application restrictions can only remove candidates, so they cannot justify an input error. Explicit specialist flags remain independent possibilities. | +| B4. An alternate-pre1956 possibility uses maximum feasible QCs and an eligible 1952Q3–1955Q4 start with at least 20 total QCs and at least six continuous credited clock quarters, under favorable all-period use or disregard. It survives unless lower credits establish 20/40 in U10's shared disabled-quarter scan. | RS .480 A requires "at least 20 quarters of coverage" and "all quarters beginning with 03/51 ... are QCs", with "at least six"; B.1 permits the first freeze day 07/01/52 through 12/31/55. RS .132 B.2 applies prior-period exclusions to the continuous alternate clock, retaining credited beginning/ending quarters; C.2 requires all periods used or all disregarded. Candidate starts obey I8/I14's latest permissible horizon, so recovery before July 1952 cannot be rescued by the first alternate start. Exclusion instead obeys U10's earliest shared date, including the two-month offset for declared ends and continuity. A lower-credit ordinary 20/40 witness in that shared interval removes the route for all credit fillings; an upper-only or later witness preserves the named refusal. Unmodeled application conditions can remove candidates but do not prove an input error. Explicit specialist flags remain independent. | | B5. Universal recent, fully-prerequisite, and annual count envelopes use zero through maximum feasible ordinary lifetime/year QCs whenever unknown periods/earnings can switch witnesses. | A213(a)(2)(B)(vi) prohibits double credit; B404.146(d) excludes interiors unless disregarded. Every concrete ordinary assignment is a subset of feasible unique lifetime quarters. The envelope permits every witness, even when adding QCs switches to a lower-count witness. Specialist possibilities remain refusals. | | B6. With known earnings and an UNKNOWN ending, returned count bounds include all end-candidate counts admitted by continuity; with entirely known facts they remain exact. | B404.120(b), .130(f), .146(d) distinguish credited endpoints and excluded interiors. All candidate quarters are enumerated, including early endpoints and capped-FRA candidates, subject to any continues-through observation; extrema therefore cover each completion. A continuity date is never inserted as a credited endpoint. No monotonic endpoint-count premise is used. | | B7. DLI lies through query without frozen exit, or through the pre-FRA-quarter/death horizon with frozen coverage; `None` is the bottom bound. A future exit cannot remove query censoring. | RS .148 defines DLI as "the last day in the last quarter" in which status is met and limits the search relative to FRA. B404.146(b) caps credits after death; A216(i)(2)(B) caps new periods. Future undeclared work is not assumed zero. Specialist routes are refused before this ordinary DLI calculation. | | B8. For a nonblind ordinary worker with no prior period, no DLI can lie more than 39 quarters after the last credited quarter. | B404.130(b)(2) requires "at least 20 QCs in the 40-quarter period ... ending with that quarter". After 39 later quarters no original QC remains. Blindness and prior-period special/exclusion routes disable this search shortcut; flagged or observable specialist routes refuse. | | B9. With unknown periods the disregard DLI is a lower bound and the permitted query/FRA/death horizon is the upper bound; unknown SSPA applicability reduces any positive DLI lower bound to `None`. | C320(a) permits favorable disregard; B404.130(f) permits counting all prior-period quarters; RS .102 B.2 imposes an additional requirement. The bound does not infer a particular recovery or history. Exemption can recover the ordinary upper witness but cannot exceed the calendar horizon. | | B10. UNKNOWN-ending DLI bounds include every end candidate. With an unresolved ongoing end, known prior history, and frozen-exit future horizon beyond query, the named DLI-horizon refusal remains. | C321(c)'s alternative endings and RS .148's last qualifying quarter permit different historical DLI witnesses. The candidate extrema bound all declared endings; no recovery beyond the query is inferred. Refusal covers the unobserved future administrative fact. | -| B11. At most 4,096 combinations of disability endpoint assignments are searched exactly. | B404.143(b) and RS .230 permit favorable assignment; B404.130(f) makes endpoint credits decisive. The limit is computational coverage, not a statutory impossibility bound: exceeding it returns `disability_boundary_assignments_unsupported`, never a false status or input error. | +| B11. At most 4,096 combinations of disability endpoint assignments are searched exactly, after any applicable impossibility proof. | B404.143(b) and RS .230 permit favorable assignment; B404.130(f) makes credited endpoints decisive. Fixed-overlap, six-QC, and I15's minimum-requirement checks precede `_boundary_variants`, including both alternate-path calls and UNKNOWN-prior-history feasibility. A remaining excess returns `disability_boundary_assignments_unsupported`; computational complexity is neither a statutory impossibility bound nor permission to retain an all-invalid declaration. | | B12. Ordinary counted windows have 13 quarters for current insurance and 40 for ordinary disability; young/subsequent special windows require half their elapsed quarters after dropping an odd remainder, with a six-QC minimum and 20/40 ceiling. | B404.120(a) says "13-quarter period"; .130(b) says "20 QCs in the 40-quarter period"; .130(c)-(d) and A216(i)(3)(B) supply the half-quarter, odd-remainder, and 6/12 alternatives. Blindness uses only the fully insured prerequisite, and pre1956/flagged specialist paths retain refusal rather than being forced through an ordinary window. | | B13. Indexed annual QC amounts are at least the prior year's statutory increment and the rounded indexed 1978 amount, with nearest-$10 rounding and $5 ties upward. | A213(d)(2) chooses "the larger of" the prior increment and indexed amount, rounded to "the next higher multiple of $10" at a $5 tie. This exact parameter calculation has no disability or specialist alternative; input-domain checks require positive NAWI and a statutory prior increment. | | B14. Declaring continuity never widens the administrative-end candidate set; every returned status and count envelope remains valid for every retained concrete ending. | C321(c)'s ending events still govern. Set intersection with ends on/after the observation can only remove candidates; it creates neither an ending nor a new credit. The universal envelope remains unchanged where other unknown facts require it. | -| B15. Ordinary establishment overlap resolution enumerates at most 4,096 unknown-credit fillings after its fixed-date monotonicity and candidate-quarter exclusion checks. | C320(b)(2) and C321(a) require one insured beginning consistent with the complete declaration. If every possible starting quarter overlaps a supplied prior period, I13 settles impossibility without enumeration. Otherwise this is a computational coverage bound. An unresolved search beyond the limit returns `disability_boundary_assignments_unsupported`; it never asserts that a concrete filling exists or proves an input error. | +| B15. Ordinary establishment overlap resolution enumerates at most 4,096 unknown-credit fillings after its fixed-date monotonicity, candidate-quarter, six-QC, and minimum-requirement proofs. | C320(b)(2) and C321(a) require one insured beginning consistent with the complete declaration. I13 settles fixed-quarter overlap and I15 settles a known-history nonblind lifetime-QC shortfall before enumeration. If neither settles the declaration, a search beyond the limit returns `disability_boundary_assignments_unsupported`; it asserts neither a concrete filling nor an input error. | | B16. A deferred raw-conversion row retains independently computable ordinary credits in its minimum and every enumerated filling, and cannot exceed feasible calendar-quarter credits in its maximum. | A213(d)(2)'s prior-increment floor bounds future annual credits above by the captured 2027 increment applied to the supplied wages plus SE income; the possibility-only lower bound is zero. Raw 1937 allocation remains zero through four because A213(b)'s half-year rule is unresolved. For separate pre1955 agriculture or pre1951 SE, supported quarterly wage credits and supported post1950 calendar-year SE credits remain fixed; unresolved additional allocation can fill only remaining allowed quarters. Both minimum and maximum fillings may violate derived overlap even when a middle filling is valid, so neither endpoint alone proves impossibility. These bounds do not adjudicate a specialist allocation or replace its refusal. | The round-5 adversarial audit revisits each row in both directions in @@ -814,7 +902,7 @@ Round 5 adds exact classification and administrative continuity: | Invariant | Hypothesis test | | --- | --- | | Over the bounded modern and pre1978 overlap grids, `InvalidFamilyInput` occurs exactly when every concrete credit filling is invalid. A surviving filling prevents rejection, while an all-invalid declaration never acquires an evaluator row. | `test_unknown_declaration_exactly_matches_all_concrete_qc_fillings`, `test_overlap_declaration_exactly_matches_every_quarter_filling` | -| The automatically detected alternate-pre1956 start obeys the same fixed declared-end and continuity bounds as an ordinary start. A bound before July 1952 cannot use the first permitted July 1, 1952 freeze; a later permissible bound preserves the specialist refusal. | `test_automatic_pre1956_start_respects_immutable_bound_property` | +| The automatically detected alternate-pre1956 start obeys the same fixed declared-end and continuity bounds as an ordinary start. A start horizon before July 1952 cannot use the first permitted July 1, 1952 freeze; a later permissible horizon preserves the specialist refusal. A recovery-only declared end must reach September to permit a July recovery month; a July continuity observation keeps the later UNKNOWN end possible. | `test_automatic_pre1956_start_respects_immutable_bound_property` | | An automatically detected historical start must fit before the actual month-before-FRA end, including when FRA and the first possible alternate start share July 1, 1952. | `test_automatic_pre1956_start_respects_fra_cap_property` | | An adjudicated section 211 exemption preserves the ordinary status/count result and one evaluator row for source-permitted post2003 and never-assigned facts; observed and convention-filled facts have equal statutory treatment. Pre2004-assigned aliens accept exactly the exempt declaration and reject declared applicability. An alien born on/after January 1, 2004 cannot supply the required possible pre2004 assignment and therefore cannot declare exemption. | `test_adjudicated_exemption_preserves_ordinary_count_and_evaluator_row`, `test_pre2004_assignment_accepts_exactly_the_exempt_applicability`, `test_wrong_number_exemption_requires_possible_pre2004_assignment` | | A continuity declaration never widens the candidate-ending set. Every returned status and count envelope agrees with or contains every retained concrete ending; no continuity observation becomes a credited endpoint. | `test_continuity_only_narrows_candidates_and_all_concrete_ends_agree` | @@ -825,24 +913,25 @@ Round 6 adds refusal ordering and settled route exclusions: | --- | --- | | Adding any of the four early raw-conversion refusal facts where it cannot change an all-invalid declaration preserves `InvalidFamilyInput`, zero rows, and zero weight, independently of mapping order. Placing it where concrete credit fillings can validate the declaration preserves the original refusal reason and note. Multiple deferred reasons retain sorted-year priority, including when an overlap search reaches its coverage limit. | `test_irrelevant_early_refusal_fact_preserves_all_invalid_grid_case`; `test_every_early_qc_refusal_preserves_possible_declaration`; `test_deferred_refusals_keep_original_sorted_year_priority`; `test_unresolved_overlap_keeps_original_deferred_refusal` | | An unsupported future increment cannot hide a fixed earlier impossible end, for zero, one, or 10,000 raw wage dollars, including the age-62 and coverage-exit interfaces. The captured increment floor can prove too few possible credits; a sufficient possible filling keeps the original refusal. All schema/history errors still precede deferred refusals. | `test_unrelated_uncaptured_increment_cannot_hide_impossible_fixed_end`; `test_uncaptured_increment_bounds_preserve_both_classifications`; `test_schema_validation_precedes_deferred_qc_refusals` | -| A lower-credit 20/40 witness in a quarter covered by every ending completion, before October 1960, makes the automatic alternate unavailable under every added unknown-credit filling. The scan includes later disabled quarters and 1960Q3 only when covered by every ending completion, excludes 1960Q4 and quarters beginning in or after the FRA month for every person, and does not substitute blindness or the young-worker rule for 20/40. A declared end includes its own quarter; an UNKNOWN end permits exclusion only through the continuity date or, without continuity, onset. An upper-only witness preserves the alternate refusal and evaluator row. | `test_fixed_twenty_of_forty_exclusion_survives_extra_unknown_credits`; `test_twenty_of_forty_before_october_1960_excludes_alternate_refusal`; `test_twenty_of_forty_scan_includes_later_disabled_quarters_before_1960`; `test_twenty_of_forty_alternate_exclusion_stops_before_october_1960`; `test_alternate_exclusion_uses_existing_disability_scan_fra_boundary`; `test_other_ordinary_disability_routes_do_not_supply_twenty_of_forty`; `test_some_twenty_of_forty_fillings_keep_named_alternate_refusal`; `test_independent_date_oracle_classifies_both_alternate_scan_directions` | +| A lower-credit 20/40 witness in a quarter disabled in every ending completion, before October 1960, makes the automatic alternate unavailable under every added unknown-credit filling. The scan includes later disabled quarters and 1960Q3 only when shared by every completion, excludes 1960Q4 and quarters beginning in or after the FRA month for every person, and does not substitute blindness or the young-worker rule for 20/40. Round 10 corrects the shared date to the declared end minus two months or continuity minus two months, never before onset; without either date it is onset. An upper-only witness preserves the alternate refusal and evaluator row. | `test_fixed_twenty_of_forty_exclusion_survives_extra_unknown_credits`; `test_twenty_of_forty_before_october_1960_excludes_alternate_refusal`; `test_twenty_of_forty_scan_includes_later_disabled_quarters_before_1960`; `test_twenty_of_forty_alternate_exclusion_stops_before_october_1960`; `test_alternate_exclusion_uses_existing_disability_scan_fra_boundary`; `test_other_ordinary_disability_routes_do_not_supply_twenty_of_forty`; `test_some_twenty_of_forty_fillings_keep_named_alternate_refusal`; `test_independent_date_oracle_classifies_both_alternate_scan_directions` | | Excluding an unavailable alternate does not reject an ordinary current establishment or prove possible nonempty prior history empty. | `test_excluding_alternate_preserves_ordinary_current_establishment`; `test_excluding_alternate_preserves_possible_nonempty_prior_history` | | If every possible starting quarter overlaps a supplied prior quarter, changing credit uncertainty cannot create a valid establishment or a refusal row, even above the filling limit. A neighboring nonoverlapping valid filling remains possible and retains the earnings refusal. | `test_immutable_overlap_is_independent_of_credit_uncertainty`; `test_fixed_same_quarter_overlap_precedes_large_filling_refusal`; `test_large_overlap_neighbour_keeps_valid_filling` | -| Deferred historical-credit fillings retain every independently guaranteed quarter. A valid middle filling prevents rejection even when both endpoints are invalid; fixing an overlapping first quarter can instead make every admissible filling invalid. Mapping order changes neither conclusion. | `test_deferred_quarter_fillings_keep_fixed_minimum_and_valid_middle` | +| Deferred historical-credit fillings retain every independently guaranteed quarter. In the corrected continuous-clock case, every filling with Q1 uncredited survives, including all-zero through the alternate route; fixing an overlapping credited Q1 makes all eight admissible fillings invalid. Mapping order changes neither conclusion. | `test_deferred_quarter_fillings_keep_fixed_minimum_and_valid_middle` | Round 7 pins the eligibility boundary independently of the ordinary scan: | Invariant | Executing tests | | --- | --- | -| For the round-7 cases, whose declared ends are the month before FRA, a 20/40 witness excludes the alternate exactly when its quarter begins before the FRA month and before October 1960, over all twelve FRA months and witness quarters. An earlier period-covered bound can further restrict exclusion, as pinned in round 8. Exclusion yields the ordinary result or a genuinely impossible declaration; non-exclusion preserves the named refusal, one evaluator row, and weight 7/3. | `test_independent_date_oracle_classifies_both_alternate_scan_directions` (Hypothesis with an independent date oracle); `test_fra_quarter_stays_only_when_it_begins_before_fra_month` | +| For the round-7 cases, whose declared ends are the month before FRA, a 20/40 witness excludes the alternate exactly when its quarter begins by the earliest shared disabled date, before the FRA month, and before October 1960, over all twelve FRA months and witness quarters. Round 10 makes that shared date two months before the declared end even when the end itself implies no recovery. Exclusion yields the ordinary result or a genuinely impossible declaration; non-exclusion preserves the named refusal, one evaluator row, and weight 7/3. | `test_independent_date_oracle_classifies_both_alternate_scan_directions` (Hypothesis with an independent date oracle); `test_fra_quarter_stays_only_when_it_begins_before_fra_month` | | Established, absent, and UNKNOWN current-period declarations share the same FRA exclusion bound. Declared-absent ordinary pre-FRA neighbours retain their results; round 9 corrects the UNKNOWN-establishment DISABILITY neighbour. | `test_unestablished_period_keeps_alternate_after_fra`; `test_unestablished_period_pre_fra_neighbour_keeps_ordinary_result`; `test_reviewed_fra_neighbours_preserve_their_public_results` | | The reviewed FRA-month witness retains the historical refusal and exact denominator weight under the ordinary query and OP12 exit; a deferred 1937 conversion retains its original reason instead. | `test_fra_month_witness_keeps_reviewed_refusal_and_denominator` | -Round 8 limits exclusion to quarters covered by every ending completion: +Round 8 limits exclusion to quarters covered by every ending completion; +round 10 corrects their shared disabled-date bound by two months: | Invariant | Executing tests | | --- | --- | -| A lower-credit 20/40 witness excludes the alternate exactly when its quarter begins on or before the established period's covered date, before the FRA month, and before October 1960. The covered date is the declared end, the continuity date for an UNKNOWN end, or onset when neither is supplied. The ending quarter remains eligible even when the end is in its middle month; the next quarter does not exclude. Both computed and refused outcomes retain one evaluator row and exact weight 11/5. | `test_declared_end_quarter_includes_witness_but_next_quarter_refuses`; `test_unknown_end_keeps_onset_witness_but_refuses_later_quarter`; `test_continuity_quarter_includes_witness_but_later_quarter_refuses`; `test_later_disabled_quarters_with_unknown_end_keep_named_refusal`; `test_october_1960_boundary_with_unknown_end_keeps_named_refusal`; `test_independent_date_oracle_classifies_covered_quarters_both_directions` (Hypothesis with an independent date oracle) | +| A lower-credit 20/40 witness excludes the alternate exactly when its quarter begins on or before the established period's earliest shared disabled month, before the FRA month, and before October 1960. That month is two months before the declared end or, for an UNKNOWN end, the continuity date, never before onset; without either fact it is onset. The recovery month's quarter remains eligible, including a month in its middle; the following quarter does not exclude. Both computed and refused outcomes retain one evaluator row and exact weight 11/5. | `test_declared_end_quarter_includes_witness_but_next_quarter_refuses`; `test_unknown_end_keeps_onset_witness_but_refuses_later_quarter`; `test_continuity_quarter_includes_witness_but_later_quarter_refuses`; `test_later_disabled_quarters_with_unknown_end_keep_named_refusal`; `test_october_1960_boundary_with_unknown_end_keeps_named_refusal`; `test_independent_date_oracle_classifies_covered_quarters_both_directions` (Hypothesis with an independent date oracle) | | If any declared-end completion preserves the named alternate refusal, an UNKNOWN ending returns no status. An onset-quarter witness remains shared by every completion; a witness in a later quarter without continuity does not. | `test_unknown_end_cannot_return_status_when_declared_completion_refuses` (Hypothesis); `test_unknown_end_keeps_onset_witness_but_refuses_later_quarter` | | The round-7 comparison's ordinary witness after the declared end preserves `disability_before_1956_unsupported`, one evaluator row, and exact weight 11/5. It cannot prove invalidity under every defensible reading. | `test_round_seven_declared_end_comparison_retains_named_refusal`; `test_alternate_exclusion_uses_existing_disability_scan_fra_boundary` | @@ -862,8 +951,10 @@ The split round-7 regression changes only its former `[unknown]` case. Both new decision sites use the same UNKNOWN-establishment predicate as `insured_status`, including onset before the FRA month. Onset at or after that boundary admits no established completion (premise U2), so neither -site applies the new restriction there. The FRA bound, established-period -covered-date bound, event scan, and repeated-work cost are unchanged. +site applies the new restriction there. Round 9 left the FRA bound, event +scan, and repeated-work cost unchanged. +Round 10 preserves those decisions and corrects only the shared disabled +month used for period-limited exclusion. The rule continues to adopt neither reading of RS .480 A. A separate prior-history audit found no corresponding disagreement. An @@ -888,6 +979,64 @@ including all refusal weights; it justifies no prior-history code change. | The independent date oracle excludes the alternate under UNKNOWN establishment exactly when the lower-credit 20/40 witness begins in the onset quarter, before the FRA month and October 1960. Later witnesses preserve the refusal. | `test_independent_date_oracle_classifies_unknown_establishment_both_ways` (Hypothesis and explicit boundary examples); `test_unknown_establishment_refuses_witness_one_quarter_after_onset` | | On the reviewed neighbour, UNKNOWN DISABILITY refuses the alternate, FULLY remains true, CURRENTLY and ALL retain their existing unknown-current refusal, and declared absence keeps all four results. The onset-quarter witness, post-1955 onset, and onset at or after FRA retain their public outcomes. | `test_reviewed_status_table_retains_rows_and_weights`; `test_unknown_fully_keeps_favorable_ordinary_witness`; `test_unknown_establishment_keeps_round_five_onset_quarter_witness`; `test_unknown_establishment_post1955_onset_keeps_ordinary_status`; `test_unknown_establishment_at_or_after_fra_keeps_existing_refusal` | +Round 10 makes recovery chronology, the alternate clock, and proof ordering +explicit: + +| Invariant | Executing tests | +| --- | --- | +| A recovery-only ending implies the month two months earlier. The recovery month cannot precede onset, and a first insured quarter beginning after that month cannot establish the period. A quarter beginning by that month can. Invalid declarations create no rows; valid outcomes retain exact weight 11/5. | `test_review_recovery_grace_quarter_cannot_establish_current_period`; `test_recovery_quarter_counts_but_next_quarter_cannot_start`; `test_recovery_month_onset_requires_smallest_two_month_gap`; `test_recovery_horizon_cannot_open_first_statutory_alternate_quarter` | +| The recovery inference stops at February 1981 and does not apply to an end in the FRA-ending month or death month. Neighboring earlier ends still infer recovery. This tests only the helper's scope and preserves existing paragraph (c) behavior. | `test_january_1981_recovery_bound_stops_at_first_paragraph_c_end`; `test_fra_ending_month_does_not_imply_recovery`; `test_death_ending_month_does_not_imply_recovery` | +| An independent plain-date oracle applies the two-month offset in both exclusion directions. A grace-month 20/40 witness cannot exclude every recovery completion; the named alternate refusal retains one row and exact weight. | `test_plain_date_oracle_applies_two_month_offset_in_both_directions` (Hypothesis); `test_review_recovery_grace_witness_keeps_alternate_refusal` | +| All-period use and disregard both apply to the alternate continuous-QC clock, with credited endpoints retained. Removing each one of the 20 QCs in the reviewed case destroys a required route condition and changes its classification to input-invalid with no row. | `test_review_prior_period_exclusions_open_alternate_continuous_clock`; `test_continuous_alternate_clock_requires_each_of_twenty_qcs` | +| A declaration with historical ends is input-invalid exactly when no enumerated concrete filling has a witness on any remaining route. The minimum-QC proof never rejects a generated declaration accepted by enumeration through the existing witness path. | `test_historical_end_exact_classification_matches_every_witness_filling`; `test_minimum_qc_proof_never_rejects_an_enumerated_witness` (Hypothesis) | +| A lifetime-QC shortfall proved before endpoint enumeration remains an input error with no evaluator row even when the boundary assignment product exceeds 4,096. A declaration at the exact minimum survives. Blindness and UNKNOWN prior exclusions retain their valid routes. | `test_impossible_fifteen_qcs_precede_boundary_complexity_without_a_row`; `test_exact_minimum_qcs_are_not_rejected_by_the_proof`; `test_blindness_keeps_six_qc_concrete_short_prior_period_route`; `test_unknown_prior_history_can_reduce_the_unseen_special_requirement` | +| Ten own QCs and declared foreign credits retain `totalization_credits_unsupported`, one row, and exact weight; three own QCs still fail the existing six-QC floor. No substantive totalized eligibility is inferred. | `test_ten_own_qcs_and_foreign_credits_keep_named_refusal_and_weight`; `test_six_own_qcs_foreign_credits_and_unknown_prior_keep_refusal`; `test_three_own_qcs_and_foreign_credits_still_fail_six_qc_floor` | + +The round-8 UNKNOWN-ending and round-9 UNKNOWN-establishment completion +properties above remain in force with the corrected shared disabled month. +The independent historical grid and generated witness enumeration do not +call the new proof to decide their expected valid fillings. + +The reviewed recovery counterexample has birth January 2, 1906, female sex, +onset July 15, 1956, and an established end May 31, 1962. Credits are +1957Q1–Q3, every quarter in 1958–1961, and 1962Q2, with zeros elsewhere. +Recovery is March 1962, before the first 20/40 quarter begins in April. +The alternate cannot apply to a 1956 onset, so the declaration is invalid. +The neighboring pre1956 example has birth May 2, 1895, onset July 15, +1955, one 1940Q1 credit, every 1951–1954 quarter, 1955Q1–Q3, and 1957Q2. +An end May 31, 1957 or UNKNOWN end with continuity through May 15, 1957 +permits recovery in March, before the first ordinary April witness. +Both FULLY and DISABILITY retain the alternate refusal and weight 11/5. + +The reviewed continuous-clock case has birth February 2, 1906, female sex, +onset January 15, 1955, end July 31, 1956, and a prior July 1, +1952–December 31, 1954 period. Every quarter in 1938–1940 and 1951, plus +Q1–Q2 in 1941 and 1952, supplies exactly 20 total QCs. Using the prior +period removes the intervening uncredited quarters from the continuous +clock. The remaining six clock quarters are 1951Q1–1952Q2, all credited. +FULLY at February 1968 therefore retains the alternate refusal, one row, +and weight 11/5. Deleting any one credit leaves either fewer than 20 total +QCs or a broken continuous clock, so no route survives. + +The UNKNOWN-prior-history continuous-clock check reuses that same invented +20-QC case. Supplying the prior period opens the alternate and refuses by +name for all four requested tests. Omitting its dates under UNKNOWN +provenance allows an unfilled prior period to remove those clock gaps, +but does not demonstrate a wrong computed Boolean: FULLY is already true +under favorable disregard, while CURRENTLY, DISABILITY, and ALL retain +`unknown_prior_disability_periods_decide_status`. `test_unknown_prior_continuous_clock_preserves_favorable_full_and_refuses_dib` +pins the public completion comparison. That eight-call comparison shows a possible alternate completion without justifying a +prior-history code change. It does not assert that UNKNOWN history is +empty or that the alternate clock is closed in every completion. + +The post-1980 check compares a January 31, 1981 end with a February 28, +1981 end. The first can imply November 1980 recovery and cannot admit a +first January 1981 insured quarter; the second falls outside the inference +and preserves the existing January witness. Ordinary modern declarations, +UNKNOWN-end enumeration, and paragraph (c) endings are otherwise left +alone. This boundary comparison makes no claim about which paragraph (c) +ending an administrative record would establish. + The invented boundary example has birth April 2, 1895, female sex, onset July 15, 1955, and an observed established period ending March 31, 1960. It has one QC in 1940Q1, all quarters credited in 1951–1954, the first @@ -902,9 +1051,10 @@ Replacing the zero 1937 row with quarterly wages of $50, $0, $0, $0 keeps `1937_earnings_allocation_unsupported` with the same row and weight. Each birth-month neighbour retains a declared end in the month before its own FRA: February 29, 1960 for the March birth and April 30, 1960 for the -May birth. The March neighbour also refuses by name; the May neighbour -computes fully insured with ordinary start April 1, 1960. These are invented -cases, not published worked examples. +May birth. Both neighbours refuse by name under round 10. The May neighbour +permits a recovery completion in February, before the first April 1960 +ordinary witness, although its April FRA ending implies no recovery fact. +These are invented cases, not published worked examples. The round-7 comparison case has birth May 2, 1888, female sex, onset July 15, 1952, observed establishment ending September 30, 1952, and observed @@ -922,15 +1072,15 @@ bound. These are invented comparisons, not published worked examples. The round-8 ending-quarter examples use birth May 2, 1895, onset July 15, 1955, and 19 ordinary recent QCs before a single later witness credit. -With a May 31 or June 30, 1956 declared end, an April 1, 1956 witness -excludes the alternate and computes the ordinary start; a July 1 witness -instead retains the named refusal. With an UNKNOWN end and a May 15, -1956 continuity observation, the April witness excludes and the July -witness refuses. Each outcome retains one row of weight 11/5. The -control born February 2, 1920 remains computed with a January 15, 1955 -onset-quarter witness even when the end is UNKNOWN; moving its first -ordinary witness one quarter later without continuity retains the -alternate refusal. +Round 10 applies the two-month offset to these comparisons: an April 1, +1956 witness cannot exclude the alternate with a May 31, 1956 end or a +May 15 continuity observation, because the shared disabled month is March. +A June 30 end instead supplies April as the shared month, so the April +quarter can exclude while July cannot. Each surviving outcome retains one +row of weight 11/5. The control born February 2, 1920 remains computed +with a January 15, 1955 onset-quarter witness even when the end is UNKNOWN; +moving its first ordinary witness one quarter later without continuity +retains the alternate refusal. No new death cap is needed. History validation rejects explicit credits after the death quarter; `_world` and `_allowed_quarters` cap every fixed @@ -990,9 +1140,11 @@ December 31, 1954, and January 1968 FULLY query, with observed facts. Credits are one in 1938, four in each of 1946–1948, one in 1949, four in 1951, and two in 1952; other years are zero. The prior has RS .480's 20 lifetime and six -continuous credits. Of the 16 concrete 1954 masks, both all-zero and -all-four are invalid; the seven with Q1 uncredited and some later credit -are valid. Raw agricultural wages of $100 preserve +continuous credits. Round 10 opens the alternate current route when prior +periods are used for the continuous clock. Of the 16 concrete 1954 masks, +all eight with Q1 uncredited are valid, including all-zero; all eight with +Q1 credited are invalid. The all-zero outcome is a named alternate refusal, +not an ordinary witness. Raw agricultural wages of $100 preserve `pre1955_agricultural_allocation_unsupported`. Adding $50 of independently credited Q1 nonagricultural wages requires Q1 in every filling: all eight are invalid and create no row. @@ -1025,8 +1177,10 @@ prior history, fourteen older QCs, and six QCs in the mandatory fails the ordinary recent-work test. A March or June 1952 declared end, or a continuity observation in either month, cannot use RS .480's first permitted July 1, 1952 start. The declaration is therefore input-invalid. -July and September bounds instead preserve the automatic historical -route and its named refusal. This source-required chronological check is +A July declared end now also fails, because it implies May recovery. A +September declared end implies July recovery and preserves the automatic +route. July and September continuity observations instead retain the +unknown-ending route and its named refusal. This source-required chronological check is independent of the ordinary possibility scan and of explicit specialist flags. A woman born July 2, 1887 reaches FRA in July 1952, so her period's latest end is June 30 and the alternate July 1 start is already @@ -1286,11 +1440,15 @@ The source conflict remains worker "though under a disability, does not have 20/40 for freeze or DIB in any quarter before 10/60". "Any quarter" supports the literal scan; "though under a disability" and "for freeze or DIB" support the narrower -scan through the declared period. C321(b), quoted above, governs these -pre-December-1980 endings and links an earlier ending to ended disability. -The former premise that an administrative end supplies no recovery evidence -was therefore wrong for this era. C321(c) can differ for post-November-1980 -endings; no wider claim about those endings is made here. +scan through the declared period. C321(b), quoted above, links a recovery +ending to the disability ending two months earlier. The former direct use of the administrative +end as the disabled date was two months too late. Validity uses the latest +possible disabled month, with FRA/death carve-outs; alternate exclusion +uses the earliest recovery completion, including at those carve-outs. +The conservative exclusion does not infer recovery from an FRA or death +ending. It preserves the named refusal because UNKNOWN must hold for every +completion. No recovery month is inferred for paragraph (c) endings, and +no wider claim about those endings is made here. The implementation keeps the named alternate refusal wherever those readings differ. A classification as `InvalidFamilyInput` requires every @@ -1303,6 +1461,13 @@ and zero rows. This module computes no payment; conditional on an otherwise payable invented $1,000 benefit, an unresolved insured route can determine whether $0 or $1,000 is payable, but neither amount is adjudicated here. +Declared totalization credits introduce no new substantive statutory +reading. After the existing six-QC contract, the route remains unmodeled +and retains its named refusal. The ten-own-QC example therefore supplies +one unsupported row rather than an unjustified input error. No captured +404.19xx text is available and no claim about totalized insurance or money +is made. + Mutation checks are recorded in [`track_b_insured_status_mutations.json`](track_b_insured_status_mutations.json). Every recorded implementation mutation was caught and reverted. diff --git a/docs/design/track_b_insured_status_mutations.json b/docs/design/track_b_insured_status_mutations.json index 563903113..fc4e8d8d3 100644 --- a/docs/design/track_b_insured_status_mutations.json +++ b/docs/design/track_b_insured_status_mutations.json @@ -2709,5 +2709,380 @@ } ], "round_9_note": "Three isolated in-memory implementation mutations were caught and discarded against the final source. Restoring the positive DISABILITY return for UNKNOWN establishment fails the reviewed status table; dropping UNKNOWN establishment from the covered-date bound fails the one-quarter-after-onset refusal; applying the alternate refusal to UNKNOWN FULLY fails its favorable ordinary-witness test. Every foreground process checked the same source SHA-256 before and after. No implementation mutation was written to disk and no existing assertion was weakened.", - "round_9_final_source_sha256": "2cc1ffae363bc7334d5e50fdc088b858ab60a28130cde20fa581690088459aa5" + "round_9_final_source_sha256": "2cc1ffae363bc7334d5e50fdc088b858ab60a28130cde20fa581690088459aa5", + "round_10_mutations": [ + { + "name": "complexity_before_impossibility_proof", + "source_sha256": "3c23dc33ffd2deb08201d3a42dccf8d58d2ee82f03f43b045c6d91b6bdadfb11", + "mutated_source_sha256": "92c26edb199c23bb4484dcb0b0e54aace33823963afe758b009f392bc108f234", + "before": " # This proof must precede the alternate's boundary enumeration and\n", + "after": " _with_current_period(person, credits, horizon, exit_month)\n # This proof must precede the alternate's boundary enumeration and\n", + "command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round10 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round10 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_10_proof_mutation.py complexity_before_impossibility_proof", + "pytest_arguments": [ + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "-q", + "tests/test_track_b_insured_status_fix_round_10_proof.py::test_impossible_fifteen_qcs_precede_boundary_complexity_without_a_row" + ], + "result": "2 failed in 9.85s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_10_proof.py::test_impossible_fifteen_qcs_precede_boundary_complexity_without_a_row[InsuredTest.FULLY]", + "tests/test_track_b_insured_status_fix_round_10_proof.py::test_impossible_fifteen_qcs_precede_boundary_complexity_without_a_row[InsuredTest.DISABILITY]" + ], + "mechanism": "Compile modified module in memory only; source SHA-256 unchanged after execution", + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round10-psid POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round10-epuf /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\np = Path(i.__file__)\noriginal = p.read_text()\nprint('source_before_sha256', hashlib.sha256(p.read_bytes()).hexdigest())\nbefore = \" # This proof must precede the alternate's boundary enumeration and\\n\"\nafter = \" _with_current_period(person, credits, horizon, exit_month)\\n # This proof must precede the alternate's boundary enumeration and\\n\"\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', 'tests/test_track_b_insured_status_fix_round_10_proof.py::test_impossible_fifteen_qcs_precede_boundary_complexity_without_a_row'])\nassert p.read_text() == original\nprint('source_after_sha256', hashlib.sha256(p.read_bytes()).hexdigest())\nraise SystemExit(result)\nPY", + "restored": true + }, + { + "name": "minimum_requirement_raised_by_one", + "source_sha256": "3c23dc33ffd2deb08201d3a42dccf8d58d2ee82f03f43b045c6d91b6bdadfb11", + "mutated_source_sha256": "f04abf91977e1f2713aed1e0616f8d7b113d0584f3c442dce770cb534da4b3db", + "before": " and maximum_qcs < _minimum_current_period_qcs(person)\n", + "after": " and maximum_qcs < _minimum_current_period_qcs(person) + 1\n", + "command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round10 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round10 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_10_proof_mutation.py minimum_requirement_raised_by_one", + "pytest_arguments": [ + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "-q", + "tests/test_track_b_insured_status_fix_round_10_proof.py::test_exact_minimum_qcs_are_not_rejected_by_the_proof" + ], + "result": "2 failed in 12.85s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_10_proof.py::test_exact_minimum_qcs_are_not_rejected_by_the_proof[False]", + "tests/test_track_b_insured_status_fix_round_10_proof.py::test_exact_minimum_qcs_are_not_rejected_by_the_proof[True]" + ], + "mechanism": "Compile modified module in memory only; source SHA-256 unchanged after execution", + "property_check": { + "command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round10 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round10 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_10_proof_mutation.py minimum_requirement_raised_by_one tests/test_track_b_insured_status_fix_round_10_proof.py::test_minimum_qc_proof_never_rejects_an_enumerated_witness", + "result": "1 failed in 7.40s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_10_proof.py::test_minimum_qc_proof_never_rejects_an_enumerated_witness" + ], + "counterexample": { + "age": 42, + "earlier": 4, + "unknowns": [ + 2020, + 2021 + ], + "prior": true, + "blind": false, + "maximum_qcs": 12 + }, + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round10-psid POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round10-epuf /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\np = Path(i.__file__)\noriginal = p.read_text()\nprint('source_before_sha256', hashlib.sha256(p.read_bytes()).hexdigest())\nbefore = ' and maximum_qcs < _minimum_current_period_qcs(person)\\n'\nafter = ' and maximum_qcs < _minimum_current_period_qcs(person) + 1\\n'\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', 'tests/test_track_b_insured_status_fix_round_10_proof.py::test_minimum_qc_proof_never_rejects_an_enumerated_witness'])\nassert p.read_text() == original\nprint('source_after_sha256', hashlib.sha256(p.read_bytes()).hexdigest())\nraise SystemExit(result)\nPY" + }, + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round10-psid POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round10-epuf /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\np = Path(i.__file__)\noriginal = p.read_text()\nprint('source_before_sha256', hashlib.sha256(p.read_bytes()).hexdigest())\nbefore = ' and maximum_qcs < _minimum_current_period_qcs(person)\\n'\nafter = ' and maximum_qcs < _minimum_current_period_qcs(person) + 1\\n'\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', 'tests/test_track_b_insured_status_fix_round_10_proof.py::test_exact_minimum_qcs_are_not_rejected_by_the_proof'])\nassert p.read_text() == original\nprint('source_after_sha256', hashlib.sha256(p.read_bytes()).hexdigest())\nraise SystemExit(result)\nPY", + "restored": true + }, + { + "name": "blindness_carveout_removed", + "source_sha256": "3c23dc33ffd2deb08201d3a42dccf8d58d2ee82f03f43b045c6d91b6bdadfb11", + "mutated_source_sha256": "890724524c1d631d38a20066c1100246de876b295ded5484965fe8ed1ae78449", + "before": " not person.statutory_blindness\n and person.prior_disability_periods_provenance\n", + "after": " person.prior_disability_periods_provenance\n", + "command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round10 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round10 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_10_proof_mutation.py blindness_carveout_removed", + "pytest_arguments": [ + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "-q", + "tests/test_track_b_insured_status_fix_round_10_proof.py::test_blindness_keeps_six_qc_concrete_short_prior_period_route" + ], + "result": "1 failed in 5.22s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_10_proof.py::test_blindness_keeps_six_qc_concrete_short_prior_period_route" + ], + "mechanism": "Compile modified module in memory only; source SHA-256 unchanged after execution", + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round10-psid POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round10-epuf /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\np = Path(i.__file__)\noriginal = p.read_text()\nprint('source_before_sha256', hashlib.sha256(p.read_bytes()).hexdigest())\nbefore = ' not person.statutory_blindness\\n and person.prior_disability_periods_provenance\\n'\nafter = ' person.prior_disability_periods_provenance\\n'\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', 'tests/test_track_b_insured_status_fix_round_10_proof.py::test_blindness_keeps_six_qc_concrete_short_prior_period_route'])\nassert p.read_text() == original\nprint('source_after_sha256', hashlib.sha256(p.read_bytes()).hexdigest())\nraise SystemExit(result)\nPY", + "restored": true + }, + { + "name": "totalization_route_removed", + "source_sha256": "3c23dc33ffd2deb08201d3a42dccf8d58d2ee82f03f43b045c6d91b6bdadfb11", + "mutated_source_sha256": "abe2b2ecde7e7b60833c66ef5dffc33795ef04f509557424bd257540ca9ae4b0", + "before": " if totalization_credits:\n return True\n", + "after": " if totalization_credits:\n pass\n", + "command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round10 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round10 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_10_proof_mutation.py totalization_route_removed", + "pytest_arguments": [ + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "-q", + "tests/test_track_b_insured_status_fix_round_10_proof.py::test_ten_own_qcs_and_foreign_credits_keep_named_refusal_and_weight" + ], + "result": "1 failed in 5.75s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_10_proof.py::test_ten_own_qcs_and_foreign_credits_keep_named_refusal_and_weight" + ], + "mechanism": "Compile modified module in memory only; source SHA-256 unchanged after execution", + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round10-psid POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round10-epuf /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\np = Path(i.__file__)\noriginal = p.read_text()\nprint('source_before_sha256', hashlib.sha256(p.read_bytes()).hexdigest())\nbefore = ' if totalization_credits:\\n return True\\n'\nafter = ' if totalization_credits:\\n pass\\n'\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', 'tests/test_track_b_insured_status_fix_round_10_proof.py::test_ten_own_qcs_and_foreign_credits_keep_named_refusal_and_weight'])\nassert p.read_text() == original\nprint('source_after_sha256', hashlib.sha256(p.read_bytes()).hexdigest())\nraise SystemExit(result)\nPY", + "restored": true + }, + { + "name": "use_end_in_start_horizon", + "source_sha256": "c85e6f53b0e4598509939733b67e214b4710870890c33a554dacd253b63e6228", + "mutated_source_sha256": "bffe30d9997f0d7249ca189c9a091206df775f17326a3cebe138a39478d1ced7", + "before": "_historical_recovery_month(person)\n or person.current_disability_period_end,", + "after": "person.current_disability_period_end,", + "command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round10 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round10 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_10_recovery_mutation.py use_end_in_start_horizon", + "pytest_arguments": [ + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "-q", + "tests/test_track_b_insured_status_fix_round_10.py::test_recovery_horizon_cannot_open_first_statutory_alternate_quarter" + ], + "result": "1 failed, 1 passed in 6.77s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_10.py::test_recovery_horizon_cannot_open_first_statutory_alternate_quarter[False]" + ], + "log": "scratch/review/round-10-use_end_in_start_horizon.log", + "mechanism": "Compile modified module in memory only; source SHA-256 unchanged after execution", + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round10-psid POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round10-epuf /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\np = Path(i.__file__)\noriginal = p.read_text()\nprint('source_before_sha256', hashlib.sha256(p.read_bytes()).hexdigest())\nbefore = '_historical_recovery_month(person)\\n or person.current_disability_period_end,'\nafter = 'person.current_disability_period_end,'\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', 'tests/test_track_b_insured_status_fix_round_10.py::test_recovery_horizon_cannot_open_first_statutory_alternate_quarter'])\nassert p.read_text() == original\nprint('source_after_sha256', hashlib.sha256(p.read_bytes()).hexdigest())\nraise SystemExit(result)\nPY", + "restored": true + }, + { + "name": "drop_1981_recovery_bound", + "source_sha256": "c85e6f53b0e4598509939733b67e214b4710870890c33a554dacd253b63e6228", + "mutated_source_sha256": "8d1145a3251a74402816478595e28ca458d832df60bb7e0115e0d4a004455eb5", + "before": "if end is None or end >= date(1981, 2, 1):", + "after": "if end is None:", + "command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round10 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round10 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_10_recovery_mutation.py drop_1981_recovery_bound", + "pytest_arguments": [ + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "-q", + "tests/test_track_b_insured_status_fix_round_10.py::test_january_1981_recovery_bound_stops_at_first_paragraph_c_end" + ], + "result": "1 failed, 1 passed in 7.19s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_10.py::test_january_1981_recovery_bound_stops_at_first_paragraph_c_end[True]" + ], + "log": "scratch/review/round-10-drop_1981_recovery_bound.log", + "mechanism": "Compile modified module in memory only; source SHA-256 unchanged after execution", + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round10-psid POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round10-epuf /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\np = Path(i.__file__)\noriginal = p.read_text()\nprint('source_before_sha256', hashlib.sha256(p.read_bytes()).hexdigest())\nbefore = 'if end is None or end >= date(1981, 2, 1):'\nafter = 'if end is None:'\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', 'tests/test_track_b_insured_status_fix_round_10.py::test_january_1981_recovery_bound_stops_at_first_paragraph_c_end'])\nassert p.read_text() == original\nprint('source_after_sha256', hashlib.sha256(p.read_bytes()).hexdigest())\nraise SystemExit(result)\nPY", + "restored": true + }, + { + "name": "drop_fra_recovery_carveout", + "source_sha256": "c85e6f53b0e4598509939733b67e214b4710870890c33a554dacd253b63e6228", + "mutated_source_sha256": "54a1b926bde51040d222fdcc78799037b57e41b9196e9f3f070e296e32aae478", + "before": "if ending_month >= fra_end.replace(day=1):", + "after": "if False:", + "command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round10 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round10 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_10_recovery_mutation.py drop_fra_recovery_carveout", + "pytest_arguments": [ + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "-q", + "tests/test_track_b_insured_status_fix_round_10.py::test_fra_ending_month_does_not_imply_recovery" + ], + "result": "1 failed, 1 passed in 3.71s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_10.py::test_fra_ending_month_does_not_imply_recovery[True]" + ], + "log": "scratch/review/round-10-drop_fra_recovery_carveout.log", + "mechanism": "Compile modified module in memory only; source SHA-256 unchanged after execution", + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round10-psid POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round10-epuf /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\np = Path(i.__file__)\noriginal = p.read_text()\nprint('source_before_sha256', hashlib.sha256(p.read_bytes()).hexdigest())\nbefore = 'if ending_month >= fra_end.replace(day=1):'\nafter = 'if False:'\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', 'tests/test_track_b_insured_status_fix_round_10.py::test_fra_ending_month_does_not_imply_recovery'])\nassert p.read_text() == original\nprint('source_after_sha256', hashlib.sha256(p.read_bytes()).hexdigest())\nraise SystemExit(result)\nPY", + "restored": true + }, + { + "name": "drop_death_recovery_carveout", + "source_sha256": "c85e6f53b0e4598509939733b67e214b4710870890c33a554dacd253b63e6228", + "mutated_source_sha256": "d20907958c7853279438ca9f378c67e7f566963f68dad5244ab03a71655bbc89", + "before": " person.death_date is not None\n and ending_month >= person.death_date.replace(day=1)", + "after": " False\n and ending_month >= person.death_date.replace(day=1)", + "command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round10 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round10 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_10_recovery_mutation.py drop_death_recovery_carveout", + "pytest_arguments": [ + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "-q", + "tests/test_track_b_insured_status_fix_round_10.py::test_death_ending_month_does_not_imply_recovery" + ], + "result": "1 failed, 1 passed in 5.94s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_10.py::test_death_ending_month_does_not_imply_recovery[True]" + ], + "log": "scratch/review/round-10-drop_death_recovery_carveout.log", + "mechanism": "Compile modified module in memory only; source SHA-256 unchanged after execution", + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round10-psid POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round10-epuf /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\np = Path(i.__file__)\noriginal = p.read_text()\nprint('source_before_sha256', hashlib.sha256(p.read_bytes()).hexdigest())\nbefore = ' person.death_date is not None\\n and ending_month >= person.death_date.replace(day=1)'\nafter = ' False\\n and ending_month >= person.death_date.replace(day=1)'\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', 'tests/test_track_b_insured_status_fix_round_10.py::test_death_ending_month_does_not_imply_recovery'])\nassert p.read_text() == original\nprint('source_after_sha256', hashlib.sha256(p.read_bytes()).hexdigest())\nraise SystemExit(result)\nPY", + "restored": true + }, + { + "name": "subtract_one_month_in_alternate_scan", + "source_sha256": "c85e6f53b0e4598509939733b67e214b4710870890c33a554dacd253b63e6228", + "mutated_source_sha256": "96997687af49779db397949dbea13cabe4c618d3a85f8f379b95378f785abbaa", + "before": "_two_months_before(dated),", + "after": "_two_months_before(dated + timedelta(days=32 - dated.day)),", + "command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round10 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round10 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_10_recovery_mutation.py subtract_one_month_in_alternate_scan", + "pytest_arguments": [ + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "-q", + "tests/test_track_b_insured_status_fix_round_10.py::test_review_recovery_grace_witness_keeps_alternate_refusal", + "tests/test_track_b_insured_status_fix_round_10.py::test_plain_date_oracle_applies_two_month_offset_in_both_directions" + ], + "result": "5 failed in 4.99s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_10.py::test_review_recovery_grace_witness_keeps_alternate_refusal[declared-InsuredTest.FULLY]", + "tests/test_track_b_insured_status_fix_round_10.py::test_review_recovery_grace_witness_keeps_alternate_refusal[declared-InsuredTest.DISABILITY]", + "tests/test_track_b_insured_status_fix_round_10.py::test_review_recovery_grace_witness_keeps_alternate_refusal[continuity-InsuredTest.FULLY]", + "tests/test_track_b_insured_status_fix_round_10.py::test_review_recovery_grace_witness_keeps_alternate_refusal[continuity-InsuredTest.DISABILITY]", + "tests/test_track_b_insured_status_fix_round_10.py::test_plain_date_oracle_applies_two_month_offset_in_both_directions" + ], + "log": "scratch/review/round-10-subtract_one_month_in_alternate_scan.log", + "mechanism": "Compile modified module in memory only; source SHA-256 unchanged after execution", + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round10-psid POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round10-epuf /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\np = Path(i.__file__)\noriginal = p.read_text()\nprint('source_before_sha256', hashlib.sha256(p.read_bytes()).hexdigest())\nbefore = '_two_months_before(dated),'\nafter = '_two_months_before(dated + timedelta(days=32 - dated.day)),'\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', 'tests/test_track_b_insured_status_fix_round_10.py::test_review_recovery_grace_witness_keeps_alternate_refusal', 'tests/test_track_b_insured_status_fix_round_10.py::test_plain_date_oracle_applies_two_month_offset_in_both_directions'])\nassert p.read_text() == original\nprint('source_after_sha256', hashlib.sha256(p.read_bytes()).hexdigest())\nraise SystemExit(result)\nPY", + "restored": true + }, + { + "name": "drop_continuous_clock_use_periods", + "source_sha256": "c85e6f53b0e4598509939733b67e214b4710870890c33a554dacd253b63e6228", + "mutated_source_sha256": "b595c35efc64239936d9deccdae6f3470889d1d96bc946b37cac182cae2f22b3", + "before": "(True, False) if person.prior_disability_periods else (True,)\n ):\n rows, periods = _world(\n person, credits, quarter, exit_month, use_periods", + "after": "(False,)\n ):\n rows, periods = _world(\n person, credits, quarter, exit_month, use_periods", + "command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round10 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round10 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_10_recovery_mutation.py drop_continuous_clock_use_periods", + "pytest_arguments": [ + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "-q", + "tests/test_track_b_insured_status_fix_round_10.py::test_review_prior_period_exclusions_open_alternate_continuous_clock", + "tests/test_track_b_insured_status_fix_round_10.py::test_continuous_alternate_clock_requires_each_of_twenty_qcs" + ], + "result": "21 failed in 21.47s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_10.py::test_review_prior_period_exclusions_open_alternate_continuous_clock", + "tests/test_track_b_insured_status_fix_round_10.py::test_continuous_alternate_clock_requires_each_of_twenty_qcs[0]", + "tests/test_track_b_insured_status_fix_round_10.py::test_continuous_alternate_clock_requires_each_of_twenty_qcs[1]", + "tests/test_track_b_insured_status_fix_round_10.py::test_continuous_alternate_clock_requires_each_of_twenty_qcs[2]", + "tests/test_track_b_insured_status_fix_round_10.py::test_continuous_alternate_clock_requires_each_of_twenty_qcs[3]", + "tests/test_track_b_insured_status_fix_round_10.py::test_continuous_alternate_clock_requires_each_of_twenty_qcs[4]", + "tests/test_track_b_insured_status_fix_round_10.py::test_continuous_alternate_clock_requires_each_of_twenty_qcs[5]", + "tests/test_track_b_insured_status_fix_round_10.py::test_continuous_alternate_clock_requires_each_of_twenty_qcs[6]", + "tests/test_track_b_insured_status_fix_round_10.py::test_continuous_alternate_clock_requires_each_of_twenty_qcs[7]", + "tests/test_track_b_insured_status_fix_round_10.py::test_continuous_alternate_clock_requires_each_of_twenty_qcs[8]", + "tests/test_track_b_insured_status_fix_round_10.py::test_continuous_alternate_clock_requires_each_of_twenty_qcs[9]", + "tests/test_track_b_insured_status_fix_round_10.py::test_continuous_alternate_clock_requires_each_of_twenty_qcs[10]", + "tests/test_track_b_insured_status_fix_round_10.py::test_continuous_alternate_clock_requires_each_of_twenty_qcs[11]", + "tests/test_track_b_insured_status_fix_round_10.py::test_continuous_alternate_clock_requires_each_of_twenty_qcs[12]", + "tests/test_track_b_insured_status_fix_round_10.py::test_continuous_alternate_clock_requires_each_of_twenty_qcs[13]", + "tests/test_track_b_insured_status_fix_round_10.py::test_continuous_alternate_clock_requires_each_of_twenty_qcs[14]", + "tests/test_track_b_insured_status_fix_round_10.py::test_continuous_alternate_clock_requires_each_of_twenty_qcs[15]", + "tests/test_track_b_insured_status_fix_round_10.py::test_continuous_alternate_clock_requires_each_of_twenty_qcs[16]", + "tests/test_track_b_insured_status_fix_round_10.py::test_continuous_alternate_clock_requires_each_of_twenty_qcs[17]", + "tests/test_track_b_insured_status_fix_round_10.py::test_continuous_alternate_clock_requires_each_of_twenty_qcs[18]", + "tests/test_track_b_insured_status_fix_round_10.py::test_continuous_alternate_clock_requires_each_of_twenty_qcs[19]" + ], + "log": "scratch/review/round-10-drop_continuous_clock_use_periods.log", + "mechanism": "Compile modified module in memory only; source SHA-256 unchanged after execution", + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round10-psid POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round10-epuf /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\np = Path(i.__file__)\noriginal = p.read_text()\nprint('source_before_sha256', hashlib.sha256(p.read_bytes()).hexdigest())\nbefore = '(True, False) if person.prior_disability_periods else (True,)\\n ):\\n rows, periods = _world(\\n person, credits, quarter, exit_month, use_periods'\nafter = '(False,)\\n ):\\n rows, periods = _world(\\n person, credits, quarter, exit_month, use_periods'\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', 'tests/test_track_b_insured_status_fix_round_10.py::test_review_prior_period_exclusions_open_alternate_continuous_clock', 'tests/test_track_b_insured_status_fix_round_10.py::test_continuous_alternate_clock_requires_each_of_twenty_qcs'])\nassert p.read_text() == original\nprint('source_after_sha256', hashlib.sha256(p.read_bytes()).hexdigest())\nraise SystemExit(result)\nPY", + "restored": true + }, + { + "name": "replace_recovery_month_with_end_for_classification", + "source_sha256": "c85e6f53b0e4598509939733b67e214b4710870890c33a554dacd253b63e6228", + "mutated_source_sha256": "abaaa0a092a21410adad02990d9ed267bd6caf58957b655f527ca0cdaccbd2eb", + "before": "return _two_months_before(end)", + "after": "return end.replace(day=1)", + "command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round10 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round10 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_10_recovery_mutation.py replace_recovery_month_with_end_for_classification", + "pytest_arguments": [ + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "-q", + "tests/test_track_b_insured_status_fix_round_10.py::test_historical_end_exact_classification_matches_every_witness_filling" + ], + "result": "1 failed in 9.47s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_10.py::test_historical_end_exact_classification_matches_every_witness_filling" + ], + "log": "scratch/review/round-10-replace_recovery_month_with_end_for_classification.log", + "mechanism": "Compile modified module in memory only; source SHA-256 unchanged after execution", + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round10-psid POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round10-epuf /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\np = Path(i.__file__)\noriginal = p.read_text()\nprint('source_before_sha256', hashlib.sha256(p.read_bytes()).hexdigest())\nbefore = 'return _two_months_before(end)'\nafter = 'return end.replace(day=1)'\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', 'tests/test_track_b_insured_status_fix_round_10.py::test_historical_end_exact_classification_matches_every_witness_filling'])\nassert p.read_text() == original\nprint('source_after_sha256', hashlib.sha256(p.read_bytes()).hexdigest())\nraise SystemExit(result)\nPY", + "restored": true + }, + { + "name": "use_latest_end_for_unknown_completion", + "source_sha256": "c85e6f53b0e4598509939733b67e214b4710870890c33a554dacd253b63e6228", + "mutated_source_sha256": "0c8c400270cce473695ea1a8197d00f8d892733758a8fc3f382b4566f007840e", + "before": " else person.disability_onset\n )", + "after": " else _current_period_start_horizon(person, month)\n )", + "command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round10 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round10 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_10_recovery_mutation.py use_latest_end_for_unknown_completion", + "pytest_arguments": [ + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "-q", + "tests/test_track_b_insured_status_fix_round_8.py::test_unknown_end_cannot_return_status_when_declared_completion_refuses", + "tests/test_track_b_insured_status_fix_round_9.py::test_unknown_establishment_cannot_compute_when_completion_refuses" + ], + "result": "2 failed in 190.08s (0:03:10)", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_8.py::test_unknown_end_cannot_return_status_when_declared_completion_refuses", + "tests/test_track_b_insured_status_fix_round_9.py::test_unknown_establishment_cannot_compute_when_completion_refuses" + ], + "log": "scratch/review/round-10-use_latest_end_for_unknown_completion.log", + "mechanism": "Compile modified module in memory only; source SHA-256 unchanged after execution", + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round10-psid POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round10-epuf /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\np = Path(i.__file__)\noriginal = p.read_text()\nprint('source_before_sha256', hashlib.sha256(p.read_bytes()).hexdigest())\nbefore = ' else person.disability_onset\\n )'\nafter = ' else _current_period_start_horizon(person, month)\\n )'\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', 'tests/test_track_b_insured_status_fix_round_8.py::test_unknown_end_cannot_return_status_when_declared_completion_refuses', 'tests/test_track_b_insured_status_fix_round_9.py::test_unknown_establishment_cannot_compute_when_completion_refuses'])\nassert p.read_text() == original\nprint('source_after_sha256', hashlib.sha256(p.read_bytes()).hexdigest())\nraise SystemExit(result)\nPY", + "restored": true + }, + { + "name": "remove_recovery_onset_check", + "source_sha256": "c85e6f53b0e4598509939733b67e214b4710870890c33a554dacd253b63e6228", + "mutated_source_sha256": "d09a949b2f38a6db2f8af8ccb9490c54da2f78c20d6e9dad622da643f5da7f1a", + "before": "if recovery is not None and recovery < self.disability_onset.replace(\n day=1\n ):", + "after": "if False and recovery < self.disability_onset.replace(\n day=1\n ):", + "command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round10 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round10 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_10_recovery_mutation.py remove_recovery_onset_check", + "pytest_arguments": [ + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "-q", + "tests/test_track_b_insured_status_fix_round_10.py::test_recovery_month_onset_requires_smallest_two_month_gap" + ], + "result": "1 failed, 1 passed in 10.31s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_10.py::test_recovery_month_onset_requires_smallest_two_month_gap[False]" + ], + "log": "scratch/review/round-10-remove_recovery_onset_check.log", + "mechanism": "Compile modified module in memory only; source SHA-256 unchanged after execution", + "reproduction_command": "env PYTHONPATH=\"$PWD/src:$PWD\" OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round10-psid POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round10-epuf /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nimport pytest\nfrom populace_dynamics.track_b import insured_status as i\np = Path(i.__file__)\noriginal = p.read_text()\nprint('source_before_sha256', hashlib.sha256(p.read_bytes()).hexdigest())\nbefore = 'if recovery is not None and recovery < self.disability_onset.replace(\\n day=1\\n ):'\nafter = 'if False and recovery < self.disability_onset.replace(\\n day=1\\n ):'\nassert original.count(before) == 1\nexec(compile(original.replace(before, after), i.__file__, 'exec'), i.__dict__)\nresult = pytest.main(['-p', 'no:xdist', '-p', 'no:cacheprovider', '-q', 'tests/test_track_b_insured_status_fix_round_10.py::test_recovery_month_onset_requires_smallest_two_month_gap'])\nassert p.read_text() == original\nprint('source_after_sha256', hashlib.sha256(p.read_bytes()).hexdigest())\nraise SystemExit(result)\nPY", + "restored": true + } + ], + "round_10_note": "Thirteen deliberate in-memory mutations were caught and discarded. Required recovery, continuous-clock, proof-order, minimum, blindness, totalization, historical-classification and completion properties bite. Each run verified the implementation file remained unchanged. Recorded per-run source hashes identify the exact source used, before the final capitalization-only module-docstring correction. Reproduction commands are self-contained and apply to the final source. No committed mutation remains.", + "round_10_final_source_sha256": "5f4dcca84c5a5b37c0092c7eb7198a8a05fed8f2cc7088deb6192575b39f1f7a" } diff --git a/src/populace_dynamics/track_b/insured_status.py b/src/populace_dynamics/track_b/insured_status.py index 54eb74496..3b4c29d12 100644 --- a/src/populace_dynamics/track_b/insured_status.py +++ b/src/populace_dynamics/track_b/insured_status.py @@ -13,8 +13,14 @@ query/cap and permitted continuation. The cap never establishes the end. The alternate test's 20/40 exclusion uses only quarters beginning before the FRA month, whether or not a period is declared established. For an -established period, the witness quarter must also begin by the declared -end, known continuity date, or onset when neither date is known. UNKNOWN +established period, the exclusion witness must also begin by the declared +end or continuity month minus two, clamped at onset, or onset when neither +date is known. This earliest-completion bound also applies to FRA/death +endings without inferring recovery from them. For ordinary validity only, +a historical recovery ending supplies the latest disabled month, two months +before the end. Endings from February 1981, FRA endings and death endings +imply no recovery month. Prior periods are all used or all disregarded in +the alternate continuous-QC clock, retaining credited endpoints. UNKNOWN establishment before FRA uses onset too: an established completion can end before a later DISABILITY witness. FULLY and CURRENTLY retain favorable disregard of the period. Declared absence keeps the ordinary result. Where @@ -26,7 +32,11 @@ scan onset and later quarters; period establishment and section 214(c) applicability carry explicit provenance. A declaration is rejected only when every ordinary and possible specialist completion is impossible; -short DIB-entitled prior periods remain possible. Observable specialist credit +assignment-independent minimum-QC proofs precede boundary complexity, skip +unknown prior histories and stop at six QCs for blindness. Foreign credits +preserve an unmodeled route after the own-QC floor; no totalized rule is +claimed here. +Short DIB-entitled prior periods remain possible. Observable specialist credit alternatives cannot silently produce ordinary-only uninsured answers. The query month is a hypothetical entitlement month, not medical or administrative adjudication. Annual QC assignment is favorable and @@ -179,6 +189,33 @@ def _attain(birth, age): return date(year, birth.month, day) - timedelta(days=1) +def _two_months_before(value): + """First day of the calendar month two months before a dated fact.""" + index = value.year * 12 + value.month - 1 - 2 + year, month = divmod(index, 12) + return date(year, month + 1, 1) + + +def _historical_recovery_month(person): + """Infer recovery only when 404.321(b) leaves no other ending cause.""" + # Source conflict us:oasdi-insured-historical-end-recovery-month + end = person.current_disability_period_end + # February 1981 is the first possible paragraph (c) ending. Infer + # nothing about recovery for an ending governed by that paragraph. + if end is None or end >= date(1981, 2, 1): + return None + ending_month = end.replace(day=1) + fra_end = _fra_date(person).replace(day=1) - timedelta(days=1) + if ending_month >= fra_end.replace(day=1): + return None + if ( + person.death_date is not None + and ending_month >= person.death_date.replace(day=1) + ): + return None + return _two_months_before(end) + + def _fact_provenance(provenance, convention_id, label): convention = provenance is EarningsProvenance.CONVENTION_FILLED if convention != (convention_id is not None): @@ -376,8 +413,6 @@ def __post_init__(self): raise InvalidFamilyInput( "Period end must close a calendar month" ) - if end < self.disability_onset: - raise InvalidFamilyInput("Current period ends before onset") if not 1870 <= self.birth_date.year <= 9900: raise InvalidFamilyInput("Birth year outside supported calendar") if self.birth_date < date(1913, 1, 2) and self.sex is None: @@ -392,6 +427,16 @@ def __post_init__(self): ): raise InvalidFamilyInput("Disability onset follows death") fra = _fra_date(self) + if ( + self.current_disability_period_end is not None + and self.current_disability_period_end < self.disability_onset + ): + raise InvalidFamilyInput("Current period ends before onset") + recovery = _historical_recovery_month(self) + if recovery is not None and recovery < self.disability_onset.replace( + day=1 + ): + raise InvalidFamilyInput("Current period recovery precedes onset") if ( self.current_disability_period_established and self.disability_onset >= fra.replace(day=1) @@ -839,15 +884,24 @@ def _pre1956_alternate_possible( person.current_disability_period_established or _current_period_establishment_unknown(person) ): - # 404.321(b): a pre-1980 period ends after disability ended or at 65. + # 404.321(b): the earliest recovery compatible with either dated + # period fact is two months earlier, including FRA/death endings. + # This is a universal-exclusion bound, not a recovery inference. # UNKNOWN establishment admits an early end and cannot supply # either an end or continuity date, so only onset is shared. - last = min( - last, + dated = ( person.current_disability_period_end or person.current_disability_period_continues_through - or person.disability_onset, ) + covered = ( + max( + person.disability_onset.replace(day=1), + _two_months_before(dated), + ) + if dated is not None + else person.disability_onset + ) + last = min(last, covered) lower = credits if lower_credits is None else lower_credits # Source conflict us:oasdi-insured-pre1956-alternate-any-quarter-scan for quarter in range( @@ -874,19 +928,30 @@ def _pre1956_alternate_possible( first = max(_qid(person.disability_onset), 1952 * 4 + 2) last = min(_qid(month), 1955 * 4 + 3) for quarter in range(first, last + 1): - rows, _ = _world(person, credits, quarter, exit_month, False) - continuous = tuple(range(1951 * 4, quarter)) - assigned = { - qc - for row in rows.values() - for qc in _assign_qcs(*row, window=continuous) - } - if ( - len(assigned) >= 20 - and len(continuous) >= 6 - and set(continuous) <= assigned + # RS00301.132 B.2/C.2: all prior periods are used or disregarded + # for the continuous clock too; credited endpoints stay eligible. + for use_periods in ( + (True, False) if person.prior_disability_periods else (True,) ): - return True + rows, periods = _world( + person, credits, quarter, exit_month, use_periods + ) + target = tuple(range(1951 * 4, quarter)) + for boundary in _boundary_variants(rows, periods): + assigned = set(_assignment(rows, target, boundary)) + continuous = tuple( + q + for q in target + if not any( + a <= q <= b and q not in assigned for a, b in periods + ) + ) + if ( + len(assigned) >= 20 + and len(continuous) >= 6 + and set(continuous) <= assigned + ): + return True return False @@ -1360,6 +1425,9 @@ def _with_current_period(person, credits, month, exit_month): end = min(end, person.death_date) if end < start: raise InvalidFamilyInput("Current period ends before insured start") + recovery = _historical_recovery_month(person) + if recovery is not None and start.replace(day=1) > recovery: + raise InvalidFamilyInput("Current period starts after recovery month") if ( person.current_disability_period_continues_through is not None and person.current_disability_period_continues_through < start @@ -1386,6 +1454,9 @@ def _current_period_completions(person, completed, start, month): End days within one quarter have identical insurance semantics. A continuity observation removes earlier endings; it never supplies an ending, including when observed later than the query. + Historical candidates may include an ending invalid under the recovery + offset. Over-inclusion can only prevent agreement and retain a refusal; + it cannot certify a status that fails a valid completion. """ if ( start is None @@ -1418,7 +1489,8 @@ def _current_period_start_horizon(person, month): """Latest possible insured start under immutable period facts.""" horizon = min(month, _fra_date(person).replace(day=1) - timedelta(days=1)) for fixed_bound in ( - person.current_disability_period_end, + _historical_recovery_month(person) + or person.current_disability_period_end, person.current_disability_period_continues_through, person.death_date, ): @@ -1427,10 +1499,8 @@ def _current_period_start_horizon(person, month): return horizon -def _specialist_establishment_possible( - person, years, credits, month, exit_month, *, lower_credits=None -): - """Overapproximate flagged/observable alternatives to ordinary insurance. +def _flagged_establishment_possible(person, years): + """Overapproximate flagged alternatives to ordinary insurance. Final direct QC declarations already supply the credited quarters; unknown years already permit four. RR annual credits after 1977 use @@ -1447,9 +1517,40 @@ def _specialist_establishment_possible( ): continue return True - return _pre1956_alternate_possible( - person, credits, month, exit_month, lower_credits=lower_credits + return False + + +def _minimum_current_period_qcs(person): + """Lower bound across ordinary and alternate establishment routes. + + 404.130(b)(2) and RS00301.480 require twenty QCs. The under31 and + subsequent-special rules may require fewer (404.130(c)/(d)). Their + elapsed-quarter count is smallest at onset with every prior-period + quarter removed, including credited endpoints. Actual treatments can + only restore quarters, and later starts can only increase elapsed + quarters. Ignoring fully insured prerequisites further lowers the + bound; this helper proves impossibility, never insurance. + + Blindness and unknown prior histories are excluded by the caller: + blindness needs only fully insured status, while missing prior + periods may supply additional exclusions or special eligibility. + """ + end = _qid(person.disability_onset) + young = end < _qid(_attain(person.birth_date, 31)) + subsequent = any( + p.special_insured for p in person.prior_disability_periods + ) + if not (young or subsequent): + return 20 + first = max(1937 * 4, _qid(_attain(person.birth_date, 21)) + 1) + elapsed = sum( + not any( + _qid(period.start) <= quarter <= _qid(period.end) + for period in person.prior_disability_periods + ) + for quarter in range(first, end + 1) ) + return min(20, max(6, elapsed // 2)) def _could_establish_current_period( @@ -1462,6 +1563,7 @@ def _could_establish_current_period( *, lower_credits=None, deferred_years=(), + totalization_credits=(), ): """Reject only a declaration impossible under every possible route. @@ -1485,12 +1587,28 @@ def _could_establish_current_period( for quarter in range(_qid(person.disability_onset), _qid(horizon) + 1) ): return False - if _specialist_establishment_possible( - person, years, credits, month, exit_month, lower_credits=lower_credits - ): + if _flagged_establishment_possible(person, years): return True if maximum_qcs < 6: return False + # Foreign coverage is an unmodeled route. After the existing own-QC + # floor, preserve its named refusal without claiming how it qualifies. + if totalization_credits: + return True + # This proof must precede the alternate's boundary enumeration and + # unknown-prior feasibility search: either can otherwise refuse before + # an assignment-independent impossibility has been established. + if ( + not person.statutory_blindness + and person.prior_disability_periods_provenance + is not EarningsProvenance.UNKNOWN + and maximum_qcs < _minimum_current_period_qcs(person) + ): + return False + if _pre1956_alternate_possible( + person, credits, month, exit_month, lower_credits=lower_credits + ): + return True rows, _ = _world(person, credits, _qid(horizon), exit_month, False) if sum(len(_assign_qcs(*row)) for row in rows.values()) < 6: return False @@ -1628,7 +1746,11 @@ def insured_status( An alternate for disability before 1956 is excluded only by 20/40 in a quarter beginning before the FRA month, independently of establishment. For established periods it must also begin by every completion's - covered date: the declared end, continuity date, or otherwise onset. + disabled month: the declared end or continuity month minus two, clamped + at onset, or otherwise onset. Validity instead uses the latest possible + disabled month: a historical recovery end minus two, without inferring + recovery from FRA, death, or paragraph (c) endings. The alternate's + continuous clock uses all prior periods or disregards all of them. UNKNOWN establishment before FRA uses onset for the same bound and cannot bypass the alternate with a later positive DISABILITY witness. FULLY and CURRENTLY retain true favorable-disregard witnesses; declared @@ -1637,6 +1759,9 @@ def insured_status( alternate refusal; post-1980 endings can differ under 404.321(c). Establishment is an input error only if no ordinary, observable, or flagged specialist route could validate any completion of the facts. + After the six-QC floor foreign credits preserve an unmodeled route; + no totalized rule is claimed. A conservative minimum-QC proof precedes + boundary complexity, except for blindness and unknown prior history. History validation runs first. Uncomputable QC rows use bounded unknown credits only for this proof; a possible declaration retains its original conversion refusal, including its reason and detail. @@ -1683,6 +1808,7 @@ def insured_status( maximum_qcs, lower_credits=lower, deferred_years=tuple(deferred), + totalization_credits=totalization_credits, ) except InsuredConfigurationUnsupported: if deferred: diff --git a/tests/README-tiers.md b/tests/README-tiers.md index 7ad540d42..c418ccba2 100644 --- a/tests/README-tiers.md +++ b/tests/README-tiers.md @@ -39,9 +39,9 @@ pytest --collect-only -q -m oracle_policyengine | tail -1 | Tier | Tests at HEAD | |---|---:| -| `unit` | 20,695 | +| `unit` | 20,748 | | `artifact` | 4,271 | | `integration_psid` | 1,471 | | `reproduction_legacy` | 520 | | `oracle_policyengine` | 308 | -| **Total** | **27,265** | +| **Total** | **27,318** | diff --git a/tests/test_track_b_insured_status_fix_round_10.py b/tests/test_track_b_insured_status_fix_round_10.py new file mode 100644 index 000000000..7baf9cfbf --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_10.py @@ -0,0 +1,460 @@ +"""Statutory conformance for recovery months and the alternate clock. + +Invented declarations only. No population, behavioral, payment, or forecast +claim. Public evaluator rows retain every refusal and its exact weight. +""" + +import calendar +from dataclasses import replace +from datetime import date +from fractions import Fraction +from itertools import product + +import pytest +from hypothesis import example, given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as i +from populace_dynamics.track_b.gross_benefits import count_family_outcomes +from tests.test_track_b_insured_status import history + +OBSERVED = i.EarningsProvenance.OBSERVED +UNKNOWN = i.EarningsProvenance.UNKNOWN +QUERY = date(1968, 1, 1) +WEIGHT = Fraction(11, 5) +ALTERNATE = i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956 + + +def _person( + *, + birth=date(1906, 1, 2), + onset=date(1956, 7, 15), + end=None, + through=None, + death=None, + prior=(), + prior_provenance=OBSERVED, +): + return i.Person( + birth, + sex=i.Sex.FEMALE, + death_date=death, + disability_onset=onset, + current_disability_period_established=True, + current_disability_period_provenance=OBSERVED, + current_disability_period_end=end, + current_disability_period_end_provenance=( + OBSERVED if end else UNKNOWN + ), + current_disability_period_continues_through=through, + current_disability_period_continues_through_provenance=( + OBSERVED if through else UNKNOWN + ), + prior_disability_periods=prior, + prior_disability_periods_provenance=prior_provenance, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + + +def _row(person, years, month=QUERY, test=i.InsuredTest.FULLY): + return i.evaluate_insured_status( + "round-ten-recovery-clock", + WEIGHT, + lambda: i.insured_status(person, years, month, test=test), + ) + + +def _assert_row(row, reason=None, *, start=None): + counts = count_family_outcomes((row,)) + assert counts.rows == 1 + assert counts.weight == WEIGHT + if reason is None: + assert row.unsupported is None + assert row.result is not None + assert counts.unsupported_rows == 0 + assert counts.unsupported_weight == 0 + if start is not None: + assert row.result.current_disability_period_start == start + else: + assert row.result is None + assert row.unsupported.reason is reason + assert counts.unsupported_rows == 1 + assert counts.unsupported_weight == WEIGHT + + +def _assert_invalid(call): + rows = [] + with pytest.raises(i.InvalidFamilyInput): + rows.append(call()) + counts = count_family_outcomes(rows) + assert counts.rows == 0 + assert counts.weight == 0 + + +def _twentieth_at(person, first_twenty, month=QUERY): + years = history(person, month) + last = first_twenty.year * 4 + (first_twenty.month - 1) // 3 + credited = set(range(last - 19, last + 1)) + for year in years: + flags = tuple(year * 4 + q in credited for q in range(4)) + years[year] = ( + i.CoverageYear(OBSERVED, qc_quarters=flags) + if year < 1978 + else i.CoverageYear(OBSERVED, qc_count=sum(flags)) + ) + return years + + +def test_review_recovery_grace_quarter_cannot_establish_current_period(): + person = _person(end=date(1962, 5, 31)) + years = history(person, QUERY, {year: 4 for year in range(1958, 1962)}) + years[1957] = i.CoverageYear( + OBSERVED, qc_quarters=(True, True, True, False) + ) + years[1962] = i.CoverageYear( + OBSERVED, qc_quarters=(False, True, False, False) + ) + _assert_invalid(lambda: _row(person, years)) + + +def _alternate_case( + witness=date(1957, 4, 1), *, end=None, through=None, fra_month=5 +): + person = _person( + birth=date(1895, fra_month, 2), + onset=date(1955, 7, 15), + end=end, + through=through, + ) + years = history(person, QUERY, {year: 4 for year in range(1951, 1955)}) + years[1940] = i.CoverageYear( + OBSERVED, qc_quarters=(True, False, False, False) + ) + years[1955] = i.CoverageYear( + OBSERVED, qc_quarters=(True, True, True, False) + ) + years[witness.year] = i.CoverageYear( + OBSERVED, + qc_quarters=tuple(q == (witness.month - 1) // 3 for q in range(4)), + ) + return person, years + + +@pytest.mark.parametrize( + "test", [i.InsuredTest.FULLY, i.InsuredTest.DISABILITY] +) +@pytest.mark.parametrize("mode", ["declared", "continuity"]) +def test_review_recovery_grace_witness_keeps_alternate_refusal(mode, test): + person, years = _alternate_case( + end=date(1957, 5, 31) if mode == "declared" else None, + through=date(1957, 5, 15) if mode == "continuity" else None, + ) + _assert_row(_row(person, years, test=test), ALTERNATE) + + +@pytest.mark.parametrize("end", [date(1962, 5, 31), date(1962, 6, 30)]) +@pytest.mark.parametrize("next_quarter", [False, True]) +def test_recovery_quarter_counts_but_next_quarter_cannot_start( + end, next_quarter +): + # May's recovery month is March; June's is April. A quarter qualifies + # when any of its months is still a disabled month. + recovery_quarter_month = 1 if end.month == 5 else 4 + start = date(1962, recovery_quarter_month + 3 * next_quarter, 1) + person = _person(end=end) + years = _twentieth_at(person, start) + if next_quarter: + _assert_invalid(lambda: _row(person, years)) + else: + _assert_row(_row(person, years), start=start) + + +@pytest.mark.parametrize("paragraph_c", [False, True]) +def test_january_1981_recovery_bound_stops_at_first_paragraph_c_end( + paragraph_c, +): + end = date(1981, 2, 28) if paragraph_c else date(1981, 1, 31) + person = _person(birth=date(1940, 2, 2), onset=date(1975, 7, 15), end=end) + month = date(1982, 1, 1) + start = date(1981, 1, 1) + years = _twentieth_at(person, start, month) + if paragraph_c: + _assert_row(_row(person, years, month), start=start) + else: + _assert_invalid(lambda: _row(person, years, month)) + + +@pytest.mark.parametrize("fra_ending", [False, True]) +def test_fra_ending_month_does_not_imply_recovery(fra_ending): + # June FRA: May is an FRA ending, but April implies February recovery. + end = date(1971, 5, 31) if fra_ending else date(1971, 4, 30) + person = _person(birth=date(1906, 6, 2), onset=date(1960, 7, 15), end=end) + month = date(1972, 1, 1) + start = date(1971, 4, 1) + years = _twentieth_at(person, start, month) + if fra_ending: + _assert_row(_row(person, years, month), start=start) + else: + _assert_invalid(lambda: _row(person, years, month)) + + +@pytest.mark.parametrize("death_ending", [False, True]) +def test_death_ending_month_does_not_imply_recovery(death_ending): + # Death in May does not imply recovery in March. An April end does. + end = date(1971, 5, 31) if death_ending else date(1971, 4, 30) + person = _person( + birth=date(1930, 2, 2), + onset=date(1960, 7, 15), + end=end, + death=date(1971, 5, 15), + ) + month = date(1972, 1, 1) + start = date(1971, 4, 1) + years = _twentieth_at(person, start, month) + if death_ending: + _assert_row(_row(person, years, month), start=start) + else: + _assert_invalid(lambda: _row(person, years, month)) + + +@pytest.mark.parametrize("valid_gap", [False, True]) +def test_recovery_month_onset_requires_smallest_two_month_gap(valid_gap): + def evaluate(): + person = _person( + birth=date(1930, 2, 2), + onset=date(1960, 1, 15), + end=date(1960, 3, 31) if valid_gap else date(1960, 2, 29), + ) + years = history(person, QUERY, {year: 4 for year in range(1955, 1960)}) + return _row(person, years) + + if valid_gap: + _assert_row(evaluate(), start=date(1960, 1, 15)) + else: + _assert_invalid(evaluate) + + +@pytest.mark.parametrize("can_start", [False, True]) +def test_recovery_horizon_cannot_open_first_statutory_alternate_quarter( + can_start, +): + person = _person( + birth=date(1906, 2, 2), + onset=date(1951, 9, 15), + end=date(1952, 9, 30) if can_start else date(1952, 8, 31), + ) + years = history( + person, QUERY, {year: 4 for year in (1938, 1939, 1940, 1951)} + ) + for year in (1941, 1952): + years[year] = i.CoverageYear( + OBSERVED, qc_quarters=(True, True, False, False) + ) + # The statutory alternate first permits a July 1952 start. An August + # end implies recovery in June; September permits that July quarter. + if can_start: + _assert_row(_row(person, years), ALTERNATE) + else: + _assert_invalid(lambda: _row(person, years)) + + +def _continuous_case(*, prior_unknown=False): + person = _person( + birth=date(1906, 2, 2), + onset=date(1955, 1, 15), + end=date(1956, 7, 31), + prior=( + () + if prior_unknown + else (i.DisabilityPeriod(date(1952, 7, 1), date(1954, 12, 31)),) + ), + prior_provenance=UNKNOWN if prior_unknown else OBSERVED, + ) + month = date(1968, 2, 1) + years = history( + person, month, {year: 4 for year in (1938, 1939, 1940, 1951)} + ) + for year in (1941, 1952): + years[year] = i.CoverageYear( + OBSERVED, qc_quarters=(True, True, False, False) + ) + return person, years, month + + +def test_unknown_prior_continuous_clock_preserves_favorable_full_and_refuses_dib(): + person, years, month = _continuous_case(prior_unknown=True) + empty = replace(person, prior_disability_periods_provenance=OBSERVED) + _assert_invalid(lambda: _row(empty, years, month)) + _assert_row(_row(_continuous_case()[0], years, month), ALTERNATE) + # Removing the hidden gaps opens the alternate route, but favorable + # disregard already guarantees FULLY independently of prior history. + # DISABILITY retains the unknown-period refusal rather than treating + # the unfilled prior history as empty. + row = _row(person, years, month) + _assert_row(row) + assert row.result.fully.insured + _assert_row( + _row(person, years, month, test=i.InsuredTest.DISABILITY), + i.InsuredUnsupportedReason.UNKNOWN_PERIODS, + ) + + +def test_review_prior_period_exclusions_open_alternate_continuous_clock(): + person, years, month = _continuous_case() + _assert_row(_row(person, years, month), ALTERNATE) + + +@pytest.mark.parametrize("deleted", range(20)) +def test_continuous_alternate_clock_requires_each_of_twenty_qcs(deleted): + person, years, month = _continuous_case() + _assert_row(_row(person, years, month), ALTERNATE) + credited = [ + (year, q) + for year, row in years.items() + for q, flag in enumerate(row.qc_quarters) + if flag + ] + year, quarter = credited[deleted] + flags = list(years[year].qc_quarters) + flags[quarter] = False + years[year] = i.CoverageYear(OBSERVED, qc_quarters=tuple(flags)) + _assert_invalid(lambda: _row(person, years, month)) + + +@settings(max_examples=24, deadline=None) +@example( + mode="declared", + ending_year=1957, + ending_month=5, + witness_year=1957, + witness_quarter=2, + fra_month=5, +) +@example( + mode="continuity", + ending_year=1957, + ending_month=5, + witness_year=1957, + witness_quarter=2, + fra_month=5, +) +@example( + mode="declared", + ending_year=1957, + ending_month=8, + witness_year=1957, + witness_quarter=2, + fra_month=5, +) +@example( + mode="continuity", + ending_year=1957, + ending_month=8, + witness_year=1957, + witness_quarter=2, + fra_month=5, +) +@given( + mode=st.sampled_from(["declared", "continuity", "unknown"]), + ending_year=st.integers(1956, 1960), + ending_month=st.integers(1, 12), + witness_year=st.integers(1956, 1960), + witness_quarter=st.integers(1, 4), + fra_month=st.integers(1, 12), +) +def test_plain_date_oracle_applies_two_month_offset_in_both_directions( + mode, ending_year, ending_month, witness_year, witness_quarter, fra_month +): + # All expected dates are plain calendar arithmetic. The only production + # operation used to classify the declaration is the public entry point. + end = date( + ending_year, + ending_month, + calendar.monthrange(ending_year, ending_month)[1], + ) + if mode == "continuity": + end = min( + end, + date.fromordinal(date(1960, fra_month, 1).toordinal() - 1), + ) + onset = date(1955, 7, 15) + index = end.year * 12 + end.month - 1 - 2 + guaranteed = max( + onset.replace(day=1), date(index // 12, index % 12 + 1, 1) + ) + if mode == "unknown": + guaranteed = onset + witness = date(witness_year, (witness_quarter - 1) * 3 + 1, 1) + excludes = ( + witness <= guaranteed + and witness < date(1960, fra_month, 1) + and witness < date(1960, 10, 1) + ) + person, years = _alternate_case( + witness, + fra_month=fra_month, + end=end if mode == "declared" else None, + through=end if mode == "continuity" else None, + ) + row = _row(person, years) + _assert_row(row, None if excludes else ALTERNATE) + assert (row.result is not None) == excludes + + +@settings(max_examples=12, deadline=None) +@example(ending_month=4, fixed_previous=18) +@given( + ending_month=st.sampled_from([3, 4, 5, 6, 9, 12]), + fixed_previous=st.integers(16, 19), +) +def test_historical_end_exact_classification_matches_every_witness_filling( + ending_month, fixed_previous +): + person = _person( + end=date( + 1962, ending_month, calendar.monthrange(1962, ending_month)[1] + ) + ) + years = history(person, QUERY) + # Credits just below twenty force a first insured quarter in 1962. + fixed = list(range(1957 * 4, 1962 * 4))[-fixed_previous:] + for year in range(1957, 1962): + years[year] = i.CoverageYear( + OBSERVED, + qc_quarters=tuple(year * 4 + q in fixed for q in range(4)), + ) + years[1962] = i.CoverageYear(UNKNOWN) + index = 1962 * 12 + ending_month - 1 - 2 + recovery = date(index // 12, index % 12 + 1, 1) + last_quarter = recovery.year * 4 + (recovery.month - 1) // 3 + any_valid = False + for flags in product((False, True), repeat=4): + filling = {**years, 1962: i.CoverageYear(OBSERVED, qc_quarters=flags)} + credits = { + year: i._credits(year, row, False) for year, row in filling.items() + } + # Enumerate the existing witness path directly; do not invoke the + # new proof or public validation to determine the expected answer. + valid = any( + i._witness( + person, + credits, + date(q // 4, (q % 4) * 3 + 1, 1), + None, + i.InsuredTest.DISABILITY, + )[0] + for q in range(1956 * 4 + 2, last_quarter + 1) + ) + any_valid |= valid + if valid: + _assert_row(_row(person, filling)) + else: + _assert_invalid(lambda filling=filling: _row(person, filling)) + if any_valid: + row = _row(person, years) + assert row.result is not None or row.unsupported is not None + counts = count_family_outcomes((row,)) + assert counts.rows == 1 and counts.weight == WEIGHT + else: + _assert_invalid(lambda: _row(person, years)) diff --git a/tests/test_track_b_insured_status_fix_round_10_proof.py b/tests/test_track_b_insured_status_fix_round_10_proof.py new file mode 100644 index 000000000..e7f731a28 --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_10_proof.py @@ -0,0 +1,244 @@ +"""Statutory conformance: prove impossibility before coverage refusals. + +Invented declarations only. No population, behavioral, or forecast claim. +The enumeration oracle uses the witness path, never the new lower bound. +""" + +from dataclasses import replace +from datetime import date +from fractions import Fraction +from itertools import product + +import pytest +from hypothesis import example, given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as i +from populace_dynamics.track_b.gross_benefits import count_family_outcomes +from tests.test_track_b_insured_status import declared, history +from tests.test_track_b_insured_status_fix_round_4_routes import ( + _short_period_case, +) + +OBSERVED = i.EarningsProvenance.OBSERVED +UNKNOWN = i.EarningsProvenance.UNKNOWN +WEIGHT = Fraction(7, 3) + + +def _person(birth=date(1960, 2, 2), onset=date(2000, 1, 15), **kwargs): + return i.Person( + birth, + disability_onset=onset, + current_disability_period_established=True, + current_disability_period_provenance=OBSERVED, + current_disability_period_end=date(onset.year, 12, 31), + current_disability_period_end_provenance=OBSERVED, + prior_disability_periods_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + **kwargs, + ) + + +def _evaluate(person, years, month, *, test=i.InsuredTest.FULLY, **kwargs): + return i.evaluate_insured_status( + "round-ten-proof", + WEIGHT, + lambda: i.insured_status(person, years, month, test=test, **kwargs), + ) + + +def _assert_row(row, reason=None): + denominator = count_family_outcomes((row,)) + assert denominator.rows == 1 + assert denominator.weight == WEIGHT + if reason is None: + assert row.result is not None + assert row.unsupported is None + assert denominator.unsupported_rows == 0 + assert denominator.unsupported_weight == 0 + else: + assert row.result is None + assert row.unsupported.reason is reason + assert denominator.unsupported_rows == 1 + assert denominator.unsupported_weight == WEIGHT + + +def _complexity_case(): + periods = ( + i.DisabilityPeriod(date(1980, 1, 15), date(1983, 12, 31), True), + *( + i.DisabilityPeriod(date(year, 1, 1), date(year, 6, 30), True) + for year in range(1984, 1989) + ), + ) + person = _person(prior_disability_periods=periods) + month = date(2022, 2, 1) + counts = {1978: 4, 1979: 2, 1988: 1} + counts.update({year: 2 for year in range(1984, 1988)}) + return person, history(person, month, counts), month + + +@pytest.mark.parametrize( + "test", [i.InsuredTest.FULLY, i.InsuredTest.DISABILITY] +) +def test_impossible_fifteen_qcs_precede_boundary_complexity_without_a_row( + test, +): + person, years, month = _complexity_case() + assert sum(row.qc_count or 0 for row in years.values()) == 15 + rows = [] + with pytest.raises(i.InvalidFamilyInput, match="no possible insured"): + rows.append(_evaluate(person, years, month, test=test)) + assert count_family_outcomes(rows).rows == 0 + assert count_family_outcomes(rows).weight == 0 + + +def test_ten_own_qcs_and_foreign_credits_keep_named_refusal_and_weight(): + person = _person() + month = date(2001, 1, 1) + years = history(person, month, {1997: 4, 1998: 4, 1999: 2}) + row = _evaluate(person, years, month, totalization_credits=("canada",)) + _assert_row(row, i.InsuredUnsupportedReason.TOTALIZATION) + + +def test_six_own_qcs_foreign_credits_and_unknown_prior_keep_refusal(): + person = replace( + _person(birth=date(2000, 2, 2), onset=date(2000, 2, 2)), + current_disability_period_end=None, + current_disability_period_end_provenance=UNKNOWN, + prior_disability_periods_provenance=UNKNOWN, + conditions=(i.CoverageCondition.RAILROAD_CREDITS,), + ) + month = date(2029, 4, 1) + row = _evaluate( + person, + history(person, month, {2028: 4, 2029: 2}), + month, + totalization_credits=("invented-foreign-credit",), + ) + _assert_row(row, i.InsuredUnsupportedReason.TOTALIZATION) + + +def test_three_own_qcs_and_foreign_credits_still_fail_six_qc_floor(): + person = _person() + month = date(2001, 1, 1) + years = history(person, month, {1999: 3}) + rows = [] + with pytest.raises(i.InvalidFamilyInput, match="no possible insured"): + rows.append( + _evaluate(person, years, month, totalization_credits=("canada",)) + ) + assert count_family_outcomes(rows).rows == 0 + + +@pytest.mark.parametrize("young", [False, True]) +def test_exact_minimum_qcs_are_not_rejected_by_the_proof(young): + person = _person( + birth=date(2000 if young else 1980, 2, 2), + onset=date(2022, 1, 15), + ) + month = date(2023, 1, 1) + counts = ( + {2020: 2, 2021: 4} + if young + else {year: 4 for year in range(2017, 2022)} + ) + row = _evaluate(person, history(person, month, counts), month) + _assert_row(row) + assert ( + row.result.current_disability_period_start == person.disability_onset + ) + assert row.result.fully.insured + + +def test_blindness_keeps_six_qc_concrete_short_prior_period_route(): + person, years, month = _short_period_case() + person = replace( + person, + prior_disability_periods_provenance=OBSERVED, + prior_disability_periods=( + i.DisabilityPeriod(date(2028, 10, 1), date(2028, 12, 31)), + ), + ) + row = _evaluate(person, years, month) + _assert_row(row) + assert row.result.fully.insured + assert row.result.fully.qc_count_lower == 6 + + +def test_unknown_prior_history_can_reduce_the_unseen_special_requirement(): + person = replace(_person(), prior_disability_periods_provenance=UNKNOWN) + month = date(2001, 1, 1) + years = history(person, month, {1978: 4, 1979: 2}) + row = _evaluate(person, years, month) + _assert_row(row, i.InsuredUnsupportedReason.UNKNOWN_PERIODS) + + +@settings(max_examples=32, deadline=None) +@example(age=22, earlier=2, unknowns=(2021,), prior=False, blind=False) +@example(age=42, earlier=0, unknowns=(2020, 2021), prior=True, blind=False) +@example(age=42, earlier=4, unknowns=(2020, 2021), prior=True, blind=False) +@given( + age=st.sampled_from([22, 29, 31, 42]), + earlier=st.integers(0, 4), + unknowns=st.sampled_from([(2021,), (2020, 2021)]), + prior=st.booleans(), + blind=st.booleans(), +) +def test_minimum_qc_proof_never_rejects_an_enumerated_witness( + age, earlier, unknowns, prior, blind +): + birth = date(2022 - age, 2, 2) + prior_start = min(2015, birth.year + 25) + person = _person( + birth=birth, + onset=date(2022, 1, 15), + statutory_blindness=blind, + prior_disability_periods=( + ( + i.DisabilityPeriod( + date(prior_start, 1, 1), date(2019, 12, 31), True + ), + ) + if prior + else () + ), + ) + month = date(2023, 1, 1) + years = history(person, month, {prior_start - 2: earlier}) + for year in unknowns: + years[year] = i.CoverageYear(UNKNOWN) + accepted = False + horizon = person.current_disability_period_end + for counts in product(range(5), repeat=len(unknowns)): + concrete = {**years} + concrete.update( + (year, declared(count)) + for year, count in zip(unknowns, counts, strict=True) + ) + credits = { + year: i._credits(year, row, True) for year, row in concrete.items() + } + # This enumerates the pre-existing witness/assignment path. It + # neither calls the proof nor replaces its bound with an oracle. + try: + i._with_current_period(person, credits, horizon, None) + except i.InvalidFamilyInput: + continue + accepted = True + if age == 42 and earlier == 4 and unknowns == (2020, 2021) and prior: + # This explicit twelve-QC subsequent-special completion keeps the + # nonblind, over31 branch of the property from being vacuous. + assert accepted + upper = {year: i._credits(year, row, True) for year, row in years.items()} + rows, _ = i._world(person, upper, i._qid(month), None, False) + maximum = sum(len(i._assign_qcs(*row)) for row in rows.values()) + if accepted: + assert i._could_establish_current_period( + person, years, upper, month, None, maximum + ) + row = _evaluate(person, years, month) + denominator = count_family_outcomes((row,)) + assert denominator.rows == 1 + assert denominator.weight == WEIGHT diff --git a/tests/test_track_b_insured_status_fix_round_3_validation.py b/tests/test_track_b_insured_status_fix_round_3_validation.py index 01b59edc8..5eb7092d8 100644 --- a/tests/test_track_b_insured_status_fix_round_3_validation.py +++ b/tests/test_track_b_insured_status_fix_round_3_validation.py @@ -65,10 +65,12 @@ def test_impossible_unknown_history_validation_precedes_coverage_refusal(): conditions=(i.CoverageCondition.RAILROAD_CREDITS,), ) month = date(2029, 4, 1) + # Three own QCs cannot pass the floor even when foreign coverage is + # declared. Six own QCs leave that unmodeled route unresolved. with pytest.raises(i.InvalidFamilyInput): i.insured_status( person, - history(person, month, {2028: 4, 2029: 2}), + history(person, month, {2028: 3}), month, totalization_credits=("invented-foreign-credit",), ) diff --git a/tests/test_track_b_insured_status_fix_round_5_possibility.py b/tests/test_track_b_insured_status_fix_round_5_possibility.py index d733bb94b..f506d3851 100644 --- a/tests/test_track_b_insured_status_fix_round_5_possibility.py +++ b/tests/test_track_b_insured_status_fix_round_5_possibility.py @@ -160,7 +160,7 @@ def test_unknown_declaration_exactly_matches_all_concrete_qc_fillings( @given( missing_year=st.integers(1968, 1971), ending=st.sampled_from( - [date(1972, 3, 31), date(1972, 12, 31), date(1973, 1, 31)] + [date(1972, 4, 30), date(1972, 12, 31), date(1973, 1, 31)] ), prior_ends_in_onset_quarter=st.booleans(), ) @@ -187,7 +187,7 @@ def test_different_fillings_cannot_separately_satisfy_end_and_overlap(): person, years, month = _prior_overlap_unknown_earnings_case() person = replace( person, - current_disability_period_end=date(1972, 3, 31), + current_disability_period_end=date(1972, 4, 30), current_disability_period_end_provenance=OBSERVED, ) valid = _assert_exact_classification(person, years, month) @@ -227,7 +227,7 @@ def test_exact_classification_keeps_each_independent_flagged_route(condition): prior_disability_periods_provenance=OBSERVED, current_disability_period_established=True, current_disability_period_provenance=OBSERVED, - current_disability_period_end=date(1952, 8, 31), + current_disability_period_end=date(1952, 9, 30), current_disability_period_end_provenance=OBSERVED, sspa211_applies=False, sspa211_provenance=OBSERVED, @@ -330,7 +330,9 @@ def test_automatic_pre1956_start_obeys_fixed_end_and_continuity(fact, bound): assert not i._decision_witness( person, upper, bound, None, i.InsuredTest.DISABILITY )[0][0] - possible = bound >= date(1952, 7, 1) + # Historical recovery ends trail the last disabled month by two months. + earliest_bound = date(1952, 9 if fact == "end" else 7, 1) + possible = bound >= earliest_bound assert _classification(person, years, month) is possible assert ( i._pre1956_alternate_possible(person, upper, month, None) is possible @@ -342,7 +344,7 @@ def test_automatic_pre1956_start_obeys_fixed_end_and_continuity(fact, bound): @example(month=6, fact="continuity") @example(month=7, fact="end") @example(month=7, fact="continuity") -@given(month=st.integers(1, 12), fact=st.sampled_from(["end", "continuity"])) +@given(month=st.integers(3, 12), fact=st.sampled_from(["end", "continuity"])) def test_automatic_pre1956_start_respects_immutable_bound_property( month, fact ): diff --git a/tests/test_track_b_insured_status_fix_round_6_ordering.py b/tests/test_track_b_insured_status_fix_round_6_ordering.py index 3957496e1..f015242b6 100644 --- a/tests/test_track_b_insured_status_fix_round_6_ordering.py +++ b/tests/test_track_b_insured_status_fix_round_6_ordering.py @@ -96,9 +96,9 @@ def _early_case(year, *, relevant): end = date(onset.year, 12, 31) counts = {1951 if year < 1952 else year + 1: 2} if not relevant: - # A January ending with at most one ordinary quarter cannot be - # established; later facts cannot repair that immutable bound. - onset, end, counts = birth, date(birth.year, 2, 28), {} + # No credits precede this early bound. The historical ending has + # the required two-month onset gap; later facts cannot repair it. + onset, end, counts = birth, date(birth.year, 4, 30), {} person = i.Person( birth, disability_onset=onset, @@ -246,7 +246,8 @@ def test_deferred_quarter_fillings_keep_fixed_minimum_and_valid_middle( ) # The supplied prior has the captured alternate's 20 total QCs and # all six continuous 1951 Q1--1952 Q2 credits. For the current onset, - # both 0000 and 1111 are invalid; seven middle fillings clear overlap. + # Removing prior-period gaps opens the alternate for 0000 too. All + # eight Q1-uncredited fillings remain possible; credited Q1 overlaps. flags = [ flags for flags in product((False, True), repeat=4) @@ -260,9 +261,7 @@ def test_deferred_quarter_fillings_keep_fixed_minimum_and_valid_middle( ) for f in flags ] - assert valid == ( - [False] * 8 if fixed_first else [False] + [True] * 7 + [False] * 8 - ) + assert valid == ([False] * 8 if fixed_first else [True] * 8 + [False] * 8) years[1954] = i.CoverageYear( OBSERVED, agricultural_wages=Fraction(100), diff --git a/tests/test_track_b_insured_status_fix_round_6_routes.py b/tests/test_track_b_insured_status_fix_round_6_routes.py index d822d0e03..e83fadb90 100644 --- a/tests/test_track_b_insured_status_fix_round_6_routes.py +++ b/tests/test_track_b_insured_status_fix_round_6_routes.py @@ -230,7 +230,7 @@ def _immutable_overlap_case(): prior_disability_periods_provenance=OBSERVED, current_disability_period_established=True, current_disability_period_provenance=OBSERVED, - current_disability_period_end=date(1977, 3, 31), + current_disability_period_end=date(1977, 4, 30), current_disability_period_end_provenance=OBSERVED, sspa211_applies=False, sspa211_provenance=OBSERVED, @@ -247,7 +247,7 @@ def test_fixed_same_quarter_overlap_precedes_large_filling_refusal(): @settings(max_examples=12, deadline=None) @given( - ending_month=st.sampled_from([2, 3]), + ending_month=st.sampled_from([4, 5]), extra_unknown=st.sampled_from([None, 1973, 1978]), ) def test_immutable_overlap_is_independent_of_credit_uncertainty( diff --git a/tests/test_track_b_insured_status_fix_round_7.py b/tests/test_track_b_insured_status_fix_round_7.py index 080e97346..49455895a 100644 --- a/tests/test_track_b_insured_status_fix_round_7.py +++ b/tests/test_track_b_insured_status_fix_round_7.py @@ -103,12 +103,9 @@ def test_fra_month_witness_keeps_reviewed_refusal_and_denominator(variant): def test_reviewed_fra_neighbours_preserve_their_public_results(fra_month): person, years = _case(fra_month=fra_month) row = _row(person, years) - if fra_month == 3: - _assert_row(row, i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956) - else: - _assert_row(row) - assert row.result.fully.insured - assert row.result.current_disability_period_start == date(1960, 4, 1) + # Even the May-FRA ending admits February recovery, before April's + # first 20/40 witness. It cannot exclude the alternate in every filling. + _assert_row(row, i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956) @pytest.mark.parametrize("fra_month", range(1, 13)) @@ -122,14 +119,9 @@ def test_fra_quarter_stays_only_when_it_begins_before_fra_month(fra_month): witness_quarter=quarter, ) row = _row(person, years) - if fra_month in (1, 4, 7, 10): - _assert_row(row, i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956) - else: - _assert_row(row) - assert row.result.fully.insured - assert row.result.current_disability_period_start == date( - 1959, (quarter - 1) * 3 + 1, 1 - ) + # A possible recovery two months before the FRA ending precedes this + # quarter even when it begins before FRA. The FRA bound still applies. + _assert_row(row, i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956) def _unestablished(person, state): @@ -193,9 +185,14 @@ def test_independent_date_oracle_classifies_both_alternate_scan_directions( # The oracle uses calendar dates alone, not production FRA/quarter helpers. # The 19 recent QCs become 20 only in the supplied witness quarter. witness_start = date(witness_year, (witness_quarter - 1) * 3 + 1, 1) - excludes_alternate = witness_start < date( - 1960, fra_month, 1 - ) and witness_start < date(1960, 10, 1) + end = date(1960, fra_month, 1) - timedelta(days=1) + index = end.year * 12 + end.month - 1 - 2 + covered = date(index // 12, index % 12 + 1, 1) + excludes_alternate = ( + witness_start <= covered + and witness_start < date(1960, fra_month, 1) + and witness_start < date(1960, 10, 1) + ) person, years = _case( fra_month=fra_month, witness_year=witness_year, diff --git a/tests/test_track_b_insured_status_fix_round_8.py b/tests/test_track_b_insured_status_fix_round_8.py index e6a061249..b69f309df 100644 --- a/tests/test_track_b_insured_status_fix_round_8.py +++ b/tests/test_track_b_insured_status_fix_round_8.py @@ -92,8 +92,9 @@ def test_declared_end_quarter_includes_witness_but_next_quarter_refuses( ): person, years = _case(date(1956, witness_month, 1), end=end) row = _row(person, years) - _assert_row(row, refused=witness_month == 7) - if witness_month == 4: + refused = witness_month == 7 or end.month == 5 + _assert_row(row, refused=refused) + if not refused: assert row.result.current_disability_period_start == date(1956, 4, 1) @@ -122,7 +123,8 @@ def test_continuity_quarter_includes_witness_but_later_quarter_refuses( person, years = _case( date(1956, witness_month, 1), through=date(1956, 5, 15) ) - _assert_row(_row(person, years), refused=witness_month == 7) + # A May continuity observation permits a March recovery completion. + _assert_row(_row(person, years), refused=True) def test_later_disabled_quarters_with_unknown_end_keep_named_refusal(): @@ -217,7 +219,7 @@ def test_round_seven_declared_end_comparison_retains_named_refusal(): ) @given( mode=st.sampled_from(["declared", "unknown", "continuity"]), - covered=st.dates(min_value=date(1955, 7, 31), max_value=date(1960, 1, 31)), + covered=st.dates(min_value=date(1955, 9, 30), max_value=date(1960, 1, 31)), witness_year=st.sampled_from([1956, 1959, 1960]), witness_quarter=st.integers(1, 4), fra_month=st.integers(1, 12), @@ -238,9 +240,13 @@ def test_independent_date_oracle_classifies_covered_quarters_both_directions( ) if mode == "unknown": covered = date(1955, 7, 15) + else: + index = covered.year * 12 + covered.month - 1 - 2 + guaranteed = date(index // 12, index % 12 + 1, 1) + covered_for_oracle = max(date(1955, 7, 1), guaranteed) witness = date(witness_year, (witness_quarter - 1) * 3 + 1, 1) excludes = ( - witness <= covered + witness <= (covered if mode == "unknown" else covered_for_oracle) and witness < fra_month_start and witness < date(1960, 10, 1) ) @@ -257,7 +263,7 @@ def test_independent_date_oracle_classifies_covered_quarters_both_directions( @settings(max_examples=12, deadline=None) -@given(witness_month=st.integers(1, 12), ending_month=st.integers(7, 12)) +@given(witness_month=st.integers(1, 12), ending_month=st.integers(9, 12)) def test_unknown_end_cannot_return_status_when_declared_completion_refuses( witness_month, ending_month ): diff --git a/tests/test_track_b_insured_status_fix_round_9.py b/tests/test_track_b_insured_status_fix_round_9.py index 44bfd72f1..8a185d5fb 100644 --- a/tests/test_track_b_insured_status_fix_round_9.py +++ b/tests/test_track_b_insured_status_fix_round_9.py @@ -174,7 +174,7 @@ def test_unknown_establishment_cannot_compute_when_completion_refuses( # witness occurs after the earliest possible declared ending. completions = [ _row(_completion(person, end), years) - for end in (date(1955, 1, 31), None) + for end in (date(1955, 3, 31), None) ] assert any( row.unsupported is not None and row.unsupported.reason is ALTERNATE @@ -191,7 +191,7 @@ def test_unknown_establishment_cannot_compute_when_completion_refuses( @settings(max_examples=6, deadline=None) -@given(ending_month=st.integers(1, 12)) +@given(ending_month=st.integers(3, 12)) def test_unknown_establishment_keeps_agreed_completion_status(ending_month): person, years = _onset_case() end = date(1955, ending_month, calendar.monthrange(1955, ending_month)[1]) diff --git a/tests/test_track_b_insured_status_sources.py b/tests/test_track_b_insured_status_sources.py index da6221628..b09080929 100644 --- a/tests/test_track_b_insured_status_sources.py +++ b/tests/test_track_b_insured_status_sources.py @@ -115,6 +115,14 @@ def source_text(source_id): "poms_rs_00301_132": [ "Do not use a freeze period if it would cause a denial of or " "reduced benefits.", + "Do not count any quarter all or part of which is in a period " + "of disability, except the beginning or ending quarters if they " + "are QCs, in determining the:", + "period of continuous QCs under the alternate insured status " + "provision.", + "When there are two or more prior periods of disability, either " + "all must be disregarded or all must be used for the current " + "period of disability when computing insured status.", ], "poms_rs_00301_140": [ "Are under a disability which began before the quarter in which " @@ -286,6 +294,10 @@ def source_text(source_id): "calendar quarter in which you were disabled.", ], "ecfr_20cfr404_321": [ + "Your period of disability ends on the last day of the month " + "before the month in which you become 65 years old or, if earlier, " + "the last day of the second month following the month in which " + "your disability ended.", "Your period of disability begins on the day your disability " "begins if you are insured for disability on that day.", "If you are not insured for disability on that day, your period " diff --git a/tests/tier_counts.json b/tests/tier_counts.json index 41c3889b6..d20d5b876 100644 --- a/tests/tier_counts.json +++ b/tests/tier_counts.json @@ -1,7 +1,7 @@ { "schema_version": 1, "counts": { - "unit": 20695, + "unit": 20748, "artifact": 4271, "integration_psid": 1471, "reproduction_legacy": 520, From ad653e7d7a986dfdd332dcc2c3e7fb87fbd927e6 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sat, 31 Oct 2026 16:40:33 -0400 Subject: [PATCH 16/46] Refuse foreign credits by name and prove shortfalls past flags (#562 round 11) Two review findings broke the classification principle. The six-QC floor ran before the foreign-credit return, but that floor comes from 404.110(b)(1), which is ordinary law, and no captured text proves it for a route that combines foreign credits. Declared foreign credits now return "possible" straight after the fixed overlap check, so zero, three, six and ten own QCs all refuse by name. A fixed overlap stays first, because no credit route can move a start. The rule claims nothing about a totalization minimum. DEEMED_FULLY_INSURED returned before the minimum-QC proof, although 404.130(a) needs one of the four rules "and you must be fully insured", so the flag can't change that proof's answer. Every flag now sits in one of four classes taken from the captures: - Fully routes (deemed, transitional, earned basis, simplified pre-1951) run after the proof and above the six-QC floor. - DISABILITY_BEFORE_1956 runs after the floor, because RS 00301.480 A needs 20 QCs. - Raw-earnings flags (railroad, fiscal year, short year) stay possible only without a complete direct-QC envelope. - Credit routes (military, Medicare government employment) stay possible. Also corrects the note's overlap grid from March to April 1972. The lane found one remaining gap: a lifetime count can meet the proof while every recent window is empty. Round 12 closes it. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 173 ++++++-- .../track_b_insured_status_mutations.json | 406 +++++++++++++++++- .../track_b/insured_status.py | 83 +++- tests/README-tiers.md | 4 +- ...ack_b_insured_status_fix_round_10_proof.py | 10 +- ...est_track_b_insured_status_fix_round_11.py | 363 ++++++++++++++++ ...b_insured_status_fix_round_3_validation.py | 34 +- ..._insured_status_fix_round_5_possibility.py | 153 +++++-- ...ck_b_insured_status_period_declarations.py | 53 ++- tests/test_track_b_insured_status_sources.py | 16 + tests/tier_counts.json | 2 +- 11 files changed, 1169 insertions(+), 128 deletions(-) create mode 100644 tests/test_track_b_insured_status_fix_round_11.py diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index a879a5952..d661dc427 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -221,11 +221,15 @@ transitional, military, railroad, or other specialist routes. A flag or observable specialist route that could validate the declaration prevents that input error and preserves a refusal row. -After the fixed-quarter overlap check, establishment validation considers -flagged specialist routes, the six-QC floor, declared totalization credits, -and then a minimum-requirement proof before invoking any alternate scan, -boundary enumeration, or UNKNOWN-prior-history feasibility scan. The proof -runs only with known prior history and without statutory blindness. Every +After the fixed-quarter overlap check, declared foreign credits preserve +their unmodeled route before every credit-count proof. Credit-route flags, +or raw-earnings flags without a complete direct-QC envelope, do likewise. +The flag classes and their captured premises are listed below. The +minimum-requirement proof then precedes fully-route flags, the ordinary +six-QC floor, the declared pre1956 alternate, and every automatic alternate +scan, boundary enumeration, or UNKNOWN-prior-history feasibility scan. +The proof runs only with known prior history and without statutory +blindness. Every remaining ordinary 20/40 or alternate route needs 20 QCs. If the earliest candidate start permits the under-31 or subsequent-special rule, the proof also takes that rule's requirement after removing every prior-period @@ -239,21 +243,21 @@ availability can only add constraints; omitting them cannot make this lower bound too high (404.130(a)–(f); RS .480 A). Blindness uses the fully insured prerequisite alone (`blindness_fully_only`), -so its proof stops at the six-QC floor. UNKNOWN prior history can supply -additional exclusions and disables the stronger minimum-requirement proof. -Declared totalization credits likewise preserve an unmodeled route after -the six-QC floor, allowing `totalization_credits_unsupported` to be raised -with its evaluator row. The rule claims nothing about how a totalized -route works; no captured totalization provision is used to infer foreign -credit requirements or benefits. The existing fewer-than-six-QC input -error remains part of the declared supported-credit contract. - -An older validation-order fixture supplied six own QCs plus declared foreign -credits and expected an input error after ordinary prerequisites failed. -The unmodeled foreign route now prevents that conclusion. The fixture uses -three own QCs to keep its validation-order purpose, and a public evaluator -regression retains the original six-QC case as a named totalization refusal. -This changes no substantive claim about totalized eligibility. +so it disables the stronger proof. UNKNOWN prior history can supply +additional exclusions and also disables that proof. A fully-route flag +then preserves its named refusal even below six actual QCs: its unmodeled +fully insured rule may replace that ordinary prerequisite. The pre1956 +alternate changes the recent test but still requires 20 QCs (RS .480 A), +so its explicit flag remains below the ordinary six-QC floor. + +Declared foreign credits receive `totalization_credits_unsupported`, with +their evaluator row and weight, for zero, three, six, or ten own QCs once +fixed chronology clears. The rule makes no claim about any totalization +minimum, eligibility, foreign-credit count, or benefit. No totalization +source is used. A fixed overlap still makes establishment impossible, +because credits cannot move a candidate start or remove a supplied prior +quarter (I13). The validation-order fixture therefore retains foreign +credits but now proves fixed overlap, rather than a credit shortfall. When prior periods are UNKNOWN, favorable disregard of every period can still decide the Boolean status even if the current period's derived @@ -562,9 +566,11 @@ a subclass of the shared `FamilyConfigurationUnsupported`. The refusal order starts with full schema and history validation, including every raw row. The establishment possibility checks then precede coverage refusals. Within those checks, fixed-quarter overlap comes first, followed -by flagged specialist possibilities, the six-QC floor, declared foreign -credits, the known-history nonblind minimum-requirement proof, and the -automatic alternate route. Only then can boundary assignments, UNKNOWN +by declared foreign credits and any credit-route flag or raw-earnings flag +without a complete direct-QC envelope. The known-history nonblind +minimum-requirement proof follows. Next come fully-route flags, the +ordinary six-QC floor, the declared pre1956 alternate, and the automatic +alternate route. Only then can boundary assignments, UNKNOWN prior-history feasibility, or concrete earnings fillings be enumerated. Neither `_unknown_prior_history_is_empty` nor an alternate-path `_boundary_variants` call can run ahead of the applicable proof. Before @@ -600,7 +606,7 @@ input. An input error propagates and creates no row. | Unknown section 214(c) applicability may change a requested status | `sspa211_applicability_unknown` | | Standalone requirement helper needs coverage history to derive a declared current period start | `current_disability_period_requires_history` | | Ongoing established current period, known prior-period history, and a frozen-exit DLI horizon beyond query | `ongoing_disability_period_dli_horizon_unsupported` | -| Any foreign totalization credits after the shared chronology and six-QC checks; the route itself remains unmodeled | `totalization_credits_unsupported` | +| Any foreign totalization credits after fixed chronology, before every credit-count proof; the route itself remains unmodeled and no totalization minimum is claimed | `totalization_credits_unsupported` | | Declared deemed nonprofit/veteran fully insured path | `deemed_fully_insured_unsupported` | | Declared transitional insured path | `transitional_insured_unsupported` | | Known section 214(c) applicability needs unimplemented work-authorization/visa adjudication, including never-assigned alien SSNs | `alien_worker_sspa211_unsupported` | @@ -614,11 +620,40 @@ input. An input error propagates and creates no row. | Pre1951 self-employment income | `pre1951_self_employment_unsupported` | | Earnings require an increment after 2027 | `qc_amount_year_unsupported` | | Query before 1968; blind query before 1973; subsequent-special query before May 1983 | `entitlement_before_1968_unsupported`, `blindness_before_1973_unsupported`, `subsequent_special_before_1983_unsupported` | -| More than 4,096 disability-boundary combinations, or unresolved ordinary-establishment overlap requiring more than 4,096 credit fillings, after the applicable fixed-quarter, six-QC, and minimum-requirement proofs | `disability_boundary_assignments_unsupported` | +| More than 4,096 disability-boundary combinations, or unresolved ordinary-establishment overlap requiring more than 4,096 credit fillings, after fixed overlap and every credit-count proof applicable to the surviving flag classes and foreign-credit declaration | `disability_boundary_assignments_unsupported` | The round-3 observable-trigger audit covers every `CoverageCondition`. -An explicit condition continues to refuse independently of its ordinary -status result. Automatic detection additionally applies where the ordinary +An explicit condition continues to refuse under its own reason when the +declaration survives every applicable impossibility proof. The following +table supplies the classification premises used by those proofs. Section +404.130(a) requires one of its four rules "and you must be fully insured"; +a rule changing only fully insured status cannot supply missing recent +credits. This classification does not adjudicate the flagged rules. + +| Flag | Captured premise and effect | Class | +| --- | --- | --- | +| `DEEMED_FULLY_INSURED` | RS .106 B.2 says "deemed fully insured for all title II purposes"; 404.110(a), .111, .112 and RS .470 concern the fully insured prerequisite. | Fully route | +| `TRANSITIONAL_INSURED` | RS .101 B.1 lists "Transitional Insured Status" beside fully insured status for spouse benefits. It is absent from 404.130's four rules and supplies no recent QC. | Fully route | +| `EARNED_BASIS` | RS .475 A says "fully insured status could be established by crediting certain wages on an earned rather than a paid basis". Its stated special method changes the fully insured prerequisite. | Fully route | +| `SIMPLIFIED_PRE1951` | Act 213(c) says "For purposes of sections 414(a) and 415(d)"; 404.110(d)(1) says "For purposes of paragraph (b) of this section". Simplified credits affect fully insured status, not the independent recent test. | Fully route | +| `DISABILITY_BEFORE_1956` | RS .480 A requires "at least 20 quarters of coverage (QC) by the end of that quarter". The alternate replaces the recent test and supplies no additional QC. | Recent test | +| `RAILROAD_CREDITS` | RS .350 A says "we may use RR compensation in determining the number of quarters of coverage (QCs)"; RS .131 also identifies freeze credits. Compensation can add QCs before a final direct-QC declaration. | Raw earnings | +| `FISCAL_TAXABLE_YEAR` | RS .220 says "we will allocate the SEI proportionately to the two calendars years"; 404.142 and .144 govern taxable-year allocation. The rule acts on earnings, not an already declared final QC count. | Raw earnings | +| `SHORT_TAXABLE_YEAR` | RS .340 B.2.b says "credit SEI equally to the calendar quarter in which the TY ends" and preceding quarters in the taxable year; 404.142 and .144 govern allocation. | Raw earnings | +| `MILITARY_CREDITS` | 404.133 says "For purposes of establishing a period of disability only, we give you quarters of coverage". Freeze-only credits may lie outside the declared ordinary rows. | Credit route | +| `MEDICARE_GOVERNMENT_EMPLOYMENT` | RS .160 A says "Use GEQCs, DQCs, and regular QCs to establish the insured status requirements for Medicare purposes." Government QCs can supplement regular QCs. | Credit route | + +For raw-earnings flags, an envelope is complete when every supplied year +is a direct `qc_count`, direct `qc_quarters`, or UNKNOWN row. I9's +direct-credit contract then already fixes or bounds the final credits; +raw-amount allocation cannot add credits outside it. Military credits +are excluded from that contract because 404.133 expressly gives freeze-only +credits. Fully-route flags remain below the recent-credit proof but above +the ordinary six-QC floor. Their named refusals survive blindness or +UNKNOWN prior history, which disable the proof, and any case meeting the +minimum. The pre1956 flag remains below that floor because it needs 20 QCs. + +Automatic detection additionally applies where the ordinary declarations reveal a potentially decisive specialist route: The pre1951 bound compares the deemed-credit aggregate with the smallest @@ -715,22 +750,22 @@ to a statutory sentence that does not state it. | I5. A supplied `special_insured` prior period begins before the age-31 attainment quarter. | B404.130(d)(1): a prior period "began before age 31" and the worker "were only insured under paragraph (c)"; (c)(1) requires age 31 not yet attained. A216(i)(3)(B)(iii) expressly uses "before the quarter" of age 31. The flag declares this particular adjudicated young-worker route, not every possible special credit regime. | | I6. An alien worker's actual pre2004 SSN assignment conflicts with declared SSPA applicability; birth on/after January 1, 2004 conflicts with declared exemption. Both never-assigned and an assigned SSN, or assignment before birth, remain invalid. A worker born before 2004 may pair a post2003 assignment or never-assigned status with an adjudicated exemption. | RS .102 B.1 says an alien assigned an SSN before 2004 "is exempt", including a nonwork SSN. B.3.b says, "If an alien worker could have legitimately been assigned an SSN before 1/1/2004, the worker is exempt from the requirements of section 211 of the SSPA." Its wrong-number SS-5 scenario issued another person's number "instead of assigning the alien worker their own SSN". Thus observed or convention-filled exemption overrides either later-assignment or never-assigned presumptions when legitimate pre2004 assignment was possible. Birth on/after January 1, 2004 rules out that exception independently of the assignment record. B.4.b's worker without an SSN "is nevertheless considered to meet the work SSN requirement" when work-authorized; meeting that requirement alone supplies no exemption. | | I7. Explicit quarterly QCs or positive quarterly wages cannot occur before birth, after the query/coverage-end quarter, or after the death quarter. Every required coverage year is declared exactly once through the earliest query, exit, or death year. | A213(a)(2)(B)(i), (v): "no quarter after the quarter in which an individual dies" and "no quarter shall be counted ... prior to the beginning of such quarter"; B404.146(a)-(b) agree. Birth and supplied-record exit caps, complete years, and no implicit zeros are interface premises. Annual counts are capped rather than dated after exit. Specialist earned-basis or additional-credit declarations remain refusals and do not reinterpret an explicit ordinary covered-quarter declaration. | -| I8. A declared current establishment is invalid only after the shared possibility check excludes every route and every feasible prior/earnings filling. One ordinary filling must satisfy its insured start, recovery or administrative end, continuity, and overlap constraints together. | C320(b)(2) requires insured disability "in the calendar quarter in which you became disabled, or in a later calendar quarter"; C321(a) chooses the first such quarter. B404.130(a) supplies four ordinary rules and RS .480 supplies the alternate historical rule. The start horizon uses an inferred recovery month when I14 permits one, otherwise the declared end, together with continuity/query/death/FRA caps. Maximum credits establish only monotone insurance by that fixed horizon. A derived prior-quarter overlap requires a single lower-credit or enumerated filling whose first start also clears that overlap. An ordinary or alternate witness after the horizon cannot supply possibility. Flagged routes, the six-QC floor, declared totalization credits, and I15's minimum-requirement proof are considered before any alternate or boundary enumeration. The alternate's 20/40 exclusion instead uses U10's earliest date shared by every completion; a later witness cannot prove impossibility under every defensible reading of RS .480 A. | -| I9. Fewer than six maximum feasible ordinary lifetime QCs proves current establishment impossible after the independent flagged specialist possibilities have been excluded. | B404.110(b)(1): "You need at least 6 QCs but not more than 40 QCs"; B404.130(a): "you must be fully insured". B404.110(a) separately names deemed veteran/nonprofit routes, and RS .131/.350 cover other credits. Those alternatives prevent applying the ordinary six-QC input-error proof to a potentially valid specialist declaration. A record composed entirely of direct final QC declarations (`qc_count` or `qc_quarters`) and UNKNOWN years already fixes or bounds all admissible QCs, including RR credits, so the RR flag cannot add quarters beyond that envelope. This is the direct-credit input contract, not a claim that ordinary RSDI credits always exhaust freeze credits: RS .131 expressly allows credits "not creditable for other" purposes. If earnings allocation or that final-credit declaration is unresolved, the RR route remains possible; RS .230 and .350 supply annual and historical RR credit rules. Period exclusions alone cannot add ordinary QCs. The automatic alternate separately needs 20 QCs; the declared foreign-credit route is handled after this existing six-own-QC contract, without a substantive totalization claim (U11). | +| I8. A declared current establishment is invalid only after the shared possibility check excludes every route and every feasible prior/earnings filling. One ordinary filling must satisfy its insured start, recovery or administrative end, continuity, and overlap constraints together. | C320(b)(2) requires insured disability "in the calendar quarter in which you became disabled, or in a later calendar quarter"; C321(a) chooses the first such quarter. B404.130(a) supplies four ordinary rules and RS .480 supplies the alternate historical rule. The start horizon uses an inferred recovery month when I14 permits one, otherwise the declared end, together with continuity/query/death/FRA caps. Maximum credits establish only monotone insurance by that fixed horizon. A derived prior-quarter overlap requires a single lower-credit or enumerated filling whose first start also clears that overlap. An ordinary or alternate witness after the horizon cannot supply possibility. Foreign credits and the flag classes determine which credit-count proofs apply, in the refusal order above, before any alternate or boundary enumeration. The alternate's 20/40 exclusion instead uses U10's earliest date shared by every completion; a later witness cannot prove impossibility under every defensible reading of RS .480 A. | +| I9. Fewer than six maximum feasible ordinary lifetime QCs proves current establishment impossible only after foreign credits, credit-route flags, unresolved raw-earnings flags, and fully-route flags have preserved their possible routes. | B404.110(b)(1): "You need at least 6 QCs but not more than 40 QCs"; B404.130(a): "you must be fully insured". The flag table supplies each exception's captured premise. A record composed entirely of direct final QC declarations (`qc_count` or `qc_quarters`) and UNKNOWN years fixes or bounds all admissible final credits from RR compensation and fiscal/short taxable-year allocation. This is the direct-credit input contract, not a claim that ordinary RSDI credits exhaust freeze-only military credits: B404.133 expressly supplies the latter, so `MILITARY_CREDITS` remains a separate credit route even with direct rows. Any raw row leaves the raw-earnings route unresolved. Period exclusions alone cannot add ordinary QCs. RS .480 A separately requires 20 QCs, so `DISABILITY_BEFORE_1956` cannot rescue a below-six declaration. No ordinary floor applies to the unmodeled foreign-credit route (U11). | | I10. The supported calendar, mandatory historical sex, and explicit establishment declaration must be supplied: birth years 1870–9900, query years through 9990, sex for births before January 2, 1913, and establishment provenance whenever onset is present. | These are interface-domain requirements. B404.110(b)(2) and .132 apply different historical male/female endpoints; B404.110(c) excludes only a period "we established for you". Missing facts are not inferred. Calendar limits reserve space for date arithmetic and assert no legal incapacity outside the implementation domain; alternative credit routes cannot supply missing declared facts. | | I11. A continues-through observation requires established disability, cannot precede medical onset or the first feasible insured start, cannot exceed the pre-FRA or death boundary, and cannot follow a declared administrative end. | C320(b)(2) and C321(a) require the insured start; A216(i)(2)(D) and C321(c) bound the period's end. A declaration that a period was in force on a date requires that date to lie within one possible period. This is a dated observation, not an asserted ending; a date later than the query is allowed. Provenance and convention identifiers follow the existing fact schema. | | I12. A raw-credit conversion refusal cannot hide established-period impossibility that every feasible filling of that row preserves. | C320(b)(2), C321(a), and B404.110(b)(1) supply the insured-start and six-QC premises. The #530 input contract puts input errors before coverage refusals. Schema validation remains first; the four conversion refusals are deferred only for this proof, with unresolved rows bounded by feasible ordinary quarters. A surviving filling preserves the original refusal reason and note rather than manufacturing a supported status. | | I13. If no starting quarter from onset through the immutable horizon clears all supplied prior-period quarters, current establishment is impossible independently of credit fillings, their count, or a specialist route. | C320(b)(2) and C321(a) require an insured beginning within that interval; I4's nonoverlapping-quarter representation applies to that same beginning. A credit route cannot move a candidate outside the fixed interval or remove a supplied prior quarter. This fixed contradiction is checked before specialist possibility and filling enumeration; it does not treat UNKNOWN prior history as supplied empty history. | | I14. A declared recovery-only historical end implies a recovery month two months earlier; recovery before the onset month or a derived start after that month is invalid. | C321(b) ends the period on "the last day of the second month following the month in which your disability ended". C320(b)(2) and B404.131(a) require an insured quarter in which the worker was disabled, so an administrative grace month cannot supply a new disabled quarter. The helper returns no recovery inference for an end on/after February 1, 1981, in/after the month preceding FRA, or in/after the death month. These carve-outs preserve the existing validity horizon and make no claim about paragraph (c) recovery or administrative ending rules. | -| I15. With known prior history, no blindness, no surviving flagged route, and no declared totalization credits, fewer maximum feasible lifetime QCs than the lowest remaining rule requirement proves establishment impossible before any coverage enumeration. | B404.130(b) needs 20 QCs; (c)–(d) permit the special half-elapsed-quarter rule with six-QC floor and 20-QC ceiling; RS .480 A also needs 20. At the earliest candidate start, remove every prior-period quarter from special elapsed time, including credited endpoints. Every actual use/disregard witness has at least those elapsed quarters, and later starts cannot reduce them. Taking the smallest applicable requirement therefore cannot exceed any true route minimum. Ignoring the fully insured prerequisite and window availability only relaxes the bound. Blindness (B404.130(e)) needs only fully insured status, and UNKNOWN prior history could remove further quarters; both disable the stronger proof. | +| I15. With known prior history, no blindness, no foreign credits, no credit-route flag, and no raw-earnings flag outside a complete direct-QC envelope, fewer maximum feasible lifetime QCs than the lowest remaining recent-rule requirement proves establishment impossible before fully-route refusals or coverage enumeration. | B404.130(a) requires a recent rule "and you must be fully insured". The flag table's fully-route rules cannot change the independent recent-credit requirement. B404.130(b) needs 20 QCs; (c)–(d) permit the special half-elapsed-quarter rule with six-QC floor and 20-QC ceiling; RS .480 A also needs 20. At the earliest candidate start, remove every prior-period quarter from special elapsed time, including credited endpoints. Every actual use/disregard witness has at least those elapsed quarters, and later starts cannot reduce them. Taking the smallest applicable requirement therefore cannot exceed any true route minimum. Ignoring the fully insured prerequisite and window availability only relaxes the bound. Blindness (B404.130(e)) needs only fully insured status, and UNKNOWN prior history could remove further quarters; both disable the stronger proof. | | ID and UNKNOWN collapse | Captured text and alternative-route defense | | --- | --- | | U1. UNKNOWN prior history can collapse to empty solely for impossibility validation when no earliest prior period could start insured, on/after birth, before current onset and the FRA end. | C320(b)(2) and C321(a) require an insured beginning without a still-earlier period. A216(i)(2)(A) permits "five full calendar months' duration or" DIB entitlement "for one or more months". The scan therefore admits a one-month period and maximum feasible earnings. Any possible ordinary or specialist starting route stops the proof. It establishes no observed empty-history fact. | | U2. UNKNOWN current establishment needs no new-period alternative if there is no medical onset or onset is at/after the statutory latest starting month. | A216(i)(2)(A)-(D) and C321 prohibit a period without disability or a nonempty pre-FRA interval. This removes an impossible new-period alternative only; it does not remove UNKNOWN prior history or an existing period's UNKNOWN administrative end. | | U3. With unknown prior/current periods, true ordinary FULLY and CURRENTLY status under favorable all-period disregard decides true. A DISABILITY witness must also survive any current-establishment completion that ends the disability before that witness. | C320(a): "If benefits ... would be denied or reduced because of a period of disability, the period of disability will not be taken into consideration." B404.130(f) also permits counting all prior quarters if favorable. RS .120 requires all periods used or all disregarded; selective exclusions are not assumed. Specialist credit regimes are refused first. | -| U4. With unknown periods, fewer than six maximum feasible QCs decides false only on the ordinary route after specialist possibilities are excluded. | B404.110(b)(1) and B404.130(a) supply the six-QC prerequisite. U3's disregard cannot manufacture credits. Deemed, transitional, foreign, military/railroad, and automatically revealed historical alternatives retain named refusals instead of using this ordinary collapse. | +| U4. With unknown periods, fewer than six maximum feasible QCs decides false only on the ordinary route after specialist possibilities are excluded; it supplies no foreign-credit impossibility proof. | B404.110(b)(1) and B404.130(a) supply the ordinary six-QC prerequisite. U3's disregard cannot manufacture credits. UNKNOWN prior history disables I15. Foreign credits, fully-route and credit-route flags, and raw-earnings flags outside a complete direct envelope preserve named refusals. The direct-envelope contract and the declared pre1956 alternate still obey I9; blindness alone supplies no credits and does not replace the ordinary fully insured prerequisite. | | U5. UNKNOWN earnings decide a requested Boolean only if all lower/upper ordinary earnings witnesses agree, under the permitted fixed-period/all-period treatments; an uncertain established start refuses only after at least one feasible filling survives. | B404.143 credits one QC for each increment, maximum four; B404.130 and .146 supply assignment/exclusion rules. Adding ordinary QCs cannot invalidate a fixed treatment. A derived start cannot be silently held fixed when the completion changes it. If a lower or upper representative cannot construct the declared period, but another single filling meets its end, continuity, and prior-overlap constraints, the public result is `unknown_earnings_years_decide_status`. If no ordinary filling can qualify by the declared end and all independent routes are impossible, it is an input error and creates no row. A deferred raw-conversion row uses temporary unknown fillings only for possibility, then retains its conversion refusal. Specialist possibilities and administrative-end candidates are considered separately. | | U6. UNKNOWN administrative end decides a status only when every end-quarter candidate from start through query/cap, plus permitted continuation, agrees, after applying any continuity lower bound. | A216(i)(2)(D) uses "whichever ... is the earlier"; C321(c)(3) includes "the last month for which you received benefits" after substantial gainful activity. Medical continuity cannot exclude early ends; a dated administrative continuity observation can. FRA/death caps limit the latest candidate and do not turn the unknown into a fact. Both ending and prior-history unknown facts remain disclosed when both are missing; UNKNOWN prior history uses the universal envelopes rather than inventing a derived current period to enumerate. The unchanged completion enumeration can include early endings rejected by I14 if declared concretely. Agreement across that larger set still implies agreement across every valid completion, while disagreement can preserve an extra refusal. An actual supplied end keeps its declared-date semantics; known ending provenance requires an ending date. | | U7. UNKNOWN SSPA applicability preserves an ordinary QC-only false status, but never a QC-only true status. | RS .102 B.2 says the worker "must meet one of the following additional requirements" and may fail "even if" the QC requirement is met. Applicability can remove ordinary insurance and cannot supply missing QCs. Known applicability retains adjudication refusal; any separate specialist path is refused first. | @@ -738,7 +773,7 @@ to a statutory sentence that does not state it. | U9. A continues-through observation removes only candidate administrative ends before its date; it never supplies an ending endpoint or removes UNKNOWN-end disclosure. | C321(c) enumerates actual ending events. Observation of a period still in force supplies a lower bound on those events, not their occurrence. Same-quarter ends remain possible, while a later-quarter observation makes the query quarter interior. | | U10. An automatic alternate-pre1956 possibility can be removed for every filling only when the lower-credit filling has ordinary 20/40 in a quarter disabled in every ending completion, before October 1960. | RS .480 A says "does not have 20/40 for freeze or DIB in any quarter before 10/60". Counts under a fixed all-period use/disregard treatment are monotone in added QCs. The scan retains query, 1960Q3, and month-before-FRA caps for every person (A216(i)(2)(D); C315(a); C321(a)–(b)). For established current periods, its shared date is the declared end minus two calendar months, or continuity date minus two when the end is UNKNOWN, or onset if neither is supplied; it is never before onset. The same two-month exclusion offset applies to FRA/death endings because an earlier recovery remains a possible completion, without inferring that it occurred. UNKNOWN establishment before FRA uses onset. A quarter counts only if its first month is on or before that shared date. RS .480 A's "any quarter" supports a wider scan, while "though under a disability" and "for freeze or DIB" support the shared disabled-quarter scan. A difference preserves the named refusal. Young-worker or blindness witnesses are not substituted for 20/40, upper-only witnesses cannot exclude every filling, and application facts remain unmodeled. | -| U11. Declared foreign totalization credits preserve an unmodeled establishment route after fixed chronology and the six-own-QC floor, and retain the named totalization refusal. | This is the existing declaration and coverage contract, not a claim derived from uncaptured totalization law. No 404.19xx provision is captured. The rule therefore does not infer totalized eligibility, foreign-credit minima, or benefit amounts, and cannot use the ordinary minimum-requirement proof to reject a ten-own-QC declaration with foreign credits. The existing fewer-than-six-own-QC controls remain input-invalid. | +| U11. Declared foreign totalization credits preserve an unmodeled establishment route immediately after fixed chronology, before every credit-count proof, and retain the named totalization refusal with their row and weight. | No captured rule establishes an own-QC floor for this unmodeled route. Ordinary B404.110(b)(1) cannot prove invalidity under every route. Zero, three, six, and ten own QCs therefore retain `totalization_credits_unsupported`; I13's fixed overlap remains invalid independently of credits. The rule makes no claim about any totalization minimum, eligibility, foreign-credit count, or benefit amount and uses no totalization source. | | ID and bound | Captured text and alternative-route defense | | --- | --- | @@ -784,13 +819,22 @@ fillings), known counts zero through four, January/March/June/December ends, and blind/nonblind workers. `test_overlap_declaration_exactly_matches_every_quarter_filling` uses four missing-year shapes, prior endings in December 1971 or January 1972, -current endings in March/December 1972 or January 1973, and every one of the +current endings in April/December 1972 or January 1973, and every one of the 16 pre1978 quarterly masks. The specialist grids retain the automatic alternate-pre1956 route and every `CoverageCondition`. -`test_exact_classification_keeps_each_independent_flagged_route` also -disables the automatic pre1956 guard, proving that each flag preserves -its route independently; the RR case supplies unresolved pre1978 -compensation rather than a final direct-QC envelope. The short-DIB grid +The specialist test is split by flag class: +`test_exact_classification_keeps_raw_earnings_flagged_routes`, +`test_exact_classification_keeps_independent_credit_routes`, and +`test_exact_classification_bounds_flags_that_add_no_declared_credit`. +Each rules out an automatic pre1956 witness to test the explicit routes +independently. Fully-route flags +are paired at a proved recent-credit shortfall and the exact minimum; +raw-earnings flags are paired with a complete direct envelope and an +unresolved raw row. Credit-route flags retain refusals with a complete +direct envelope, while the declared pre1956 route cannot bypass a +below-six shortfall. Blindness and UNKNOWN prior history preserve the +fully-route flags where the recent-credit proof is inapplicable. The +short-DIB grid supplies empty and three one-month prior-history fillings. Each concrete declaration either raises an input error or survives as a status/refusal; the UNKNOWN declaration must be invalid exactly when all @@ -990,7 +1034,37 @@ explicit: | All-period use and disregard both apply to the alternate continuous-QC clock, with credited endpoints retained. Removing each one of the 20 QCs in the reviewed case destroys a required route condition and changes its classification to input-invalid with no row. | `test_review_prior_period_exclusions_open_alternate_continuous_clock`; `test_continuous_alternate_clock_requires_each_of_twenty_qcs` | | A declaration with historical ends is input-invalid exactly when no enumerated concrete filling has a witness on any remaining route. The minimum-QC proof never rejects a generated declaration accepted by enumeration through the existing witness path. | `test_historical_end_exact_classification_matches_every_witness_filling`; `test_minimum_qc_proof_never_rejects_an_enumerated_witness` (Hypothesis) | | A lifetime-QC shortfall proved before endpoint enumeration remains an input error with no evaluator row even when the boundary assignment product exceeds 4,096. A declaration at the exact minimum survives. Blindness and UNKNOWN prior exclusions retain their valid routes. | `test_impossible_fifteen_qcs_precede_boundary_complexity_without_a_row`; `test_exact_minimum_qcs_are_not_rejected_by_the_proof`; `test_blindness_keeps_six_qc_concrete_short_prior_period_route`; `test_unknown_prior_history_can_reduce_the_unseen_special_requirement` | -| Ten own QCs and declared foreign credits retain `totalization_credits_unsupported`, one row, and exact weight; three own QCs still fail the existing six-QC floor. No substantive totalized eligibility is inferred. | `test_ten_own_qcs_and_foreign_credits_keep_named_refusal_and_weight`; `test_six_own_qcs_foreign_credits_and_unknown_prior_keep_refusal`; `test_three_own_qcs_and_foreign_credits_still_fail_six_qc_floor` | +| Declared foreign credits retain `totalization_credits_unsupported`, one row, and exact weight once fixed chronology clears. Round 11 removes round 10's unsupported six-own-QC floor, including the three-own-QC case. No totalization minimum or substantive eligibility is inferred. | `test_ten_own_qcs_and_foreign_credits_keep_named_refusal_and_weight`; `test_six_own_qcs_foreign_credits_and_unknown_prior_keep_refusal`; `test_three_own_qcs_and_foreign_credits_keep_named_refusal_and_weight`; `test_foreign_credit_refusal_is_independent_of_own_qc_count` | + +Round 11 applies the flag premises to the same proof and retains exact +denominators: + +| Invariant | Executing tests | +| --- | --- | +| Adding foreign credits to a declaration clearing fixed chronology always preserves the totalization refusal, one row, and exact weight, independently of its own-QC count or flags. Fixed overlap still produces an input error and no row. | `test_foreign_credit_refusal_is_independent_of_own_qc_count` (Hypothesis); `test_foreign_credits_refuse_without_an_own_qc_floor`; `test_fixed_overlap_precedes_every_flag_and_foreign_route` | +| With known prior history and no blindness, any flag set supplying no additional credit under the complete direct-envelope contract leaves a total-QC shortfall below the recent-rule minimum input-invalid. The expected minimum is computed independently of `_minimum_current_period_qcs`; this numerical proof does not decide every temporal shortfall described below. | `test_no_credit_flag_set_cannot_hide_independently_proved_shortfall` (Hypothesis); `test_no_credit_flag_shortfall_and_exact_minimum_pair`; `test_review_recent_credit_shortfall_cannot_be_cured_by_deeming` | +| A flag cannot turn a declaration meeting every ordinary requirement into an input error. At the exact ordinary or under31 minimum, each flag retains its own reason, one row, and exact weight. | `test_no_flag_rejects_declaration_meeting_every_requirement` (Hypothesis); `test_no_credit_flag_shortfall_and_exact_minimum_pair`; `test_credit_route_keeps_refusal_even_with_complete_direct_envelope` | +| Fully-route flags retain their named refusals with blindness below six actual QCs or UNKNOWN prior history. The declared pre1956 alternate cannot bypass the ordinary six-QC floor even with blindness, but at 20 QCs retains its refusal. | `test_fully_route_refuses_when_recent_credit_proof_does_not_apply`; `test_pre1956_flag_with_blindness_keeps_ordinary_six_qc_floor` | +| A complete direct envelope bounds every raw-earnings flag, including UNKNOWN rows; a raw row preserves its unmodeled allocation route. Military and Medicare government credits preserve a separate route even with direct rows. Combining flags preserves each independent route. | `test_raw_earnings_flag_preserves_route_only_without_direct_envelope`; `test_exact_classification_bounds_flags_that_add_no_declared_credit`; `test_credit_route_keeps_refusal_even_with_complete_direct_envelope`; `test_two_flag_classes_preserve_each_independent_route` | + +Round 11 has a remaining temporal limit. Its numerical recent-credit proof +does not test whether sufficient total credits fall inside any candidate +window before a fully-route flag returns possible. An invented worker born +February 2, 1960, with onset January 15, 2000, an established period ending +December 31, 2000, known empty prior history, no blindness, and 20 direct +QCs entirely in 1978–1982 has zero QCs in every 2000 candidate 40-quarter +window. Without a flag the declaration is invalid. Each fully-route flag +instead retains its named refusal, one row, and weight 13/7 under the +prescribed order. Reducing the total to 19 makes every such flagged +declaration invalid under the numerical proof. Section 404.130(b)(2) +requires 20 QCs in the 40-quarter period, independently of fully insured +status under paragraph (a); the fully-route premises above supply no +recent-window credits. This residual is conservative over-refusal rather +than evidence of a concrete valid completion. The scratch regression +`test_fully_only_flag_cannot_supply_missing_recent_window_qcs` records the +four failing cases. The requested numerical-proof correction leaves the +later temporal scan unchanged; this additional ordering issue remains +unfixed. The round-8 UNKNOWN-ending and round-9 UNKNOWN-establishment completion properties above remain in force with the corrected shared disabled month. @@ -1462,11 +1536,24 @@ payable invented $1,000 benefit, an unresolved insured route can determine whether $0 or $1,000 is payable, but neither amount is adjudicated here. Declared totalization credits introduce no new substantive statutory -reading. After the existing six-QC contract, the route remains unmodeled -and retains its named refusal. The ten-own-QC example therefore supplies -one unsupported row rather than an unjustified input error. No captured -404.19xx text is available and no claim about totalized insurance or money -is made. +reading. Round 11 removes the unsupported own-six-QC floor: once fixed +chronology clears, the unmodeled route retains its named refusal for zero, +three, six, and ten own QCs, one row, and weight 11/5. This is a +classification correction. The rule makes no claim about any totalization +minimum, eligibility, foreign-credit count, or money and uses no +totalization source. + +Round 11 also moves the recent-credit impossibility proof ahead of the +fully-route flags. Section 404.130(a) requires a recent rule "and you must +be fully insured"; RS .106 B.2's "deemed fully insured for all title II +purposes" changes the latter prerequisite only. For the reviewed worker +born January 2, 1924, six QCs in 1984–1985 cannot meet 20/40 for a 1985 +established period, even with `DEEMED_FULLY_INSURED`. The corrected result +is an input error and zero rows; 20 recent QCs preserve the deemed-full +refusal, one row, and weight 11/5. The fully-route, recent-test, +raw-earnings, and credit-route classifications above follow the captured +premises and introduce no additional discretionary reading. Neither +finding adjudicates payment, so it establishes no dollar change. Mutation checks are recorded in [`track_b_insured_status_mutations.json`](track_b_insured_status_mutations.json). diff --git a/docs/design/track_b_insured_status_mutations.json b/docs/design/track_b_insured_status_mutations.json index fc4e8d8d3..faa9654b6 100644 --- a/docs/design/track_b_insured_status_mutations.json +++ b/docs/design/track_b_insured_status_mutations.json @@ -3084,5 +3084,409 @@ } ], "round_10_note": "Thirteen deliberate in-memory mutations were caught and discarded. Required recovery, continuous-clock, proof-order, minimum, blindness, totalization, historical-classification and completion properties bite. Each run verified the implementation file remained unchanged. Recorded per-run source hashes identify the exact source used, before the final capitalization-only module-docstring correction. Reproduction commands are self-contained and apply to the final source. No committed mutation remains.", - "round_10_final_source_sha256": "5f4dcca84c5a5b37c0092c7eb7198a8a05fed8f2cc7088deb6192575b39f1f7a" + "round_10_final_source_sha256": "5f4dcca84c5a5b37c0092c7eb7198a8a05fed8f2cc7088deb6192575b39f1f7a", + "round_11_mutations": [ + { + "name": "floor_above_foreign_return", + "source_sha256": "aebd9223724bc6694e320590a72cd744cb7309dbcb92600bd7ffb11f5d4ca4d1", + "mutated_source_sha256": "a91184b71dd508e3ed318c58cb7f6358d85e8c4b0a378c031e6d46bd5270a5ed", + "changes": [ + { + "before": " if maximum_qcs < 6:\n return False\n", + "after": "" + }, + { + "before": " if totalization_credits:\n return True\n", + "after": " if maximum_qcs < 6:\n return False\n if totalization_credits:\n return True\n" + } + ], + "command": "env PYTHONPATH=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/src:/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11 OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round11 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round11 TRACKB_ROUND11_MUTATION=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/scratch/review/round-11-mutation-floor_above_foreign_return.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_11_named.py -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_11.py::test_foreign_credit_refusal_is_independent_of_own_qc_count", + "pytest_arguments": [ + "-q", + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "--tb=short", + "tests/test_track_b_insured_status_fix_round_11.py::test_foreign_credit_refusal_is_independent_of_own_qc_count" + ], + "result": "1 failed in 4.04s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_11.py::test_foreign_credit_refusal_is_independent_of_own_qc_count" + ], + "reproduction_command": "env PYTHONPATH=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/src:/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11 OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round11 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round11 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nfrom populace_dynamics.track_b import insured_status as i\np = Path(i.__file__)\noriginal = p.read_bytes()\nassert hashlib.sha256(original).hexdigest() == 'aebd9223724bc6694e320590a72cd744cb7309dbcb92600bd7ffb11f5d4ca4d1'\nmodified = original.decode()\nbefore = ' if maximum_qcs < 6:\\n return False\\n'\nafter = ''\nassert modified.count(before) == 1\nmodified = modified.replace(before, after, 1)\nbefore = ' if totalization_credits:\\n return True\\n'\nafter = ' if maximum_qcs < 6:\\n return False\\n if totalization_credits:\\n return True\\n'\nassert modified.count(before) == 1\nmodified = modified.replace(before, after, 1)\nexec(compile(modified, i.__file__, \"exec\"), i.__dict__)\nimport pytest\nresult = pytest.main(['-q', '-p', 'no:xdist', '-p', 'no:cacheprovider', '--tb=short', 'tests/test_track_b_insured_status_fix_round_11.py::test_foreign_credit_refusal_is_independent_of_own_qc_count'])\nassert p.read_bytes() == original\nraise SystemExit(result)\nPY", + "mechanism": "Compile modified module in memory only; source bytes unchanged after execution", + "restored": true, + "open_audit": { + "restricted_opens": 0, + "subprocess.Popen": 0, + "os.system": 0 + } + }, + { + "name": "proof_below_fully_route_return", + "source_sha256": "aebd9223724bc6694e320590a72cd744cb7309dbcb92600bd7ffb11f5d4ca4d1", + "mutated_source_sha256": "ebecb0ab45f188b45431c4060922f29568a9f803ba563b50ce835be2380ca450", + "changes": [ + { + "before": " if (\n not person.statutory_blindness\n and person.prior_disability_periods_provenance\n is not EarningsProvenance.UNKNOWN\n and maximum_qcs < _minimum_current_period_qcs(person)\n ):\n return False\n if person.conditions & _FULLY_INSURED_ROUTE_CONDITIONS:\n return True\n", + "after": " if person.conditions & _FULLY_INSURED_ROUTE_CONDITIONS:\n return True\n if (\n not person.statutory_blindness\n and person.prior_disability_periods_provenance\n is not EarningsProvenance.UNKNOWN\n and maximum_qcs < _minimum_current_period_qcs(person)\n ):\n return False\n" + } + ], + "command": "env PYTHONPATH=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/src:/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11 OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round11 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round11 TRACKB_ROUND11_MUTATION=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/scratch/review/round-11-mutation-proof_below_fully_route_return.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_11_named.py -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_11.py::test_no_credit_flag_set_cannot_hide_independently_proved_shortfall", + "pytest_arguments": [ + "-q", + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "--tb=short", + "tests/test_track_b_insured_status_fix_round_11.py::test_no_credit_flag_set_cannot_hide_independently_proved_shortfall" + ], + "result": "1 failed in 2.04s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_11.py::test_no_credit_flag_set_cannot_hide_independently_proved_shortfall" + ], + "reproduction_command": "env PYTHONPATH=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/src:/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11 OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round11 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round11 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nfrom populace_dynamics.track_b import insured_status as i\np = Path(i.__file__)\noriginal = p.read_bytes()\nassert hashlib.sha256(original).hexdigest() == 'aebd9223724bc6694e320590a72cd744cb7309dbcb92600bd7ffb11f5d4ca4d1'\nmodified = original.decode()\nbefore = ' if (\\n not person.statutory_blindness\\n and person.prior_disability_periods_provenance\\n is not EarningsProvenance.UNKNOWN\\n and maximum_qcs < _minimum_current_period_qcs(person)\\n ):\\n return False\\n if person.conditions & _FULLY_INSURED_ROUTE_CONDITIONS:\\n return True\\n'\nafter = ' if person.conditions & _FULLY_INSURED_ROUTE_CONDITIONS:\\n return True\\n if (\\n not person.statutory_blindness\\n and person.prior_disability_periods_provenance\\n is not EarningsProvenance.UNKNOWN\\n and maximum_qcs < _minimum_current_period_qcs(person)\\n ):\\n return False\\n'\nassert modified.count(before) == 1\nmodified = modified.replace(before, after, 1)\nexec(compile(modified, i.__file__, \"exec\"), i.__dict__)\nimport pytest\nresult = pytest.main(['-q', '-p', 'no:xdist', '-p', 'no:cacheprovider', '--tb=short', 'tests/test_track_b_insured_status_fix_round_11.py::test_no_credit_flag_set_cannot_hide_independently_proved_shortfall'])\nassert p.read_bytes() == original\nraise SystemExit(result)\nPY", + "mechanism": "Compile modified module in memory only; source bytes unchanged after execution", + "restored": true, + "open_audit": { + "restricted_opens": 0, + "subprocess.Popen": 0, + "os.system": 0 + } + }, + { + "name": "floor_above_fully_route_return", + "source_sha256": "aebd9223724bc6694e320590a72cd744cb7309dbcb92600bd7ffb11f5d4ca4d1", + "mutated_source_sha256": "966fd2bbed9c36ee8eb698de18d511f53ec7266fd6b15cc516983e01b98c91ca", + "changes": [ + { + "before": " if person.conditions & _FULLY_INSURED_ROUTE_CONDITIONS:\n return True\n if maximum_qcs < 6:\n return False\n", + "after": " if maximum_qcs < 6:\n return False\n if person.conditions & _FULLY_INSURED_ROUTE_CONDITIONS:\n return True\n" + } + ], + "command": "env PYTHONPATH=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/src:/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11 OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round11 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round11 TRACKB_ROUND11_MUTATION=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/scratch/review/round-11-mutation-floor_above_fully_route_return.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_11_named.py -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_11.py::test_fully_route_refuses_when_recent_credit_proof_does_not_apply", + "pytest_arguments": [ + "-q", + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "--tb=short", + "tests/test_track_b_insured_status_fix_round_11.py::test_fully_route_refuses_when_recent_credit_proof_does_not_apply" + ], + "result": "8 failed, 4 passed in 7.24s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_11.py::test_fully_route_refuses_when_recent_credit_proof_does_not_apply[blind-3-CoverageCondition.DEEMED_FULLY_INSURED]", + "tests/test_track_b_insured_status_fix_round_11.py::test_fully_route_refuses_when_recent_credit_proof_does_not_apply[blind-3-CoverageCondition.TRANSITIONAL_INSURED]", + "tests/test_track_b_insured_status_fix_round_11.py::test_fully_route_refuses_when_recent_credit_proof_does_not_apply[blind-3-CoverageCondition.EARNED_BASIS]", + "tests/test_track_b_insured_status_fix_round_11.py::test_fully_route_refuses_when_recent_credit_proof_does_not_apply[blind-3-CoverageCondition.SIMPLIFIED_PRE1951]", + "tests/test_track_b_insured_status_fix_round_11.py::test_fully_route_refuses_when_recent_credit_proof_does_not_apply[unknown-prior-3-CoverageCondition.DEEMED_FULLY_INSURED]", + "tests/test_track_b_insured_status_fix_round_11.py::test_fully_route_refuses_when_recent_credit_proof_does_not_apply[unknown-prior-3-CoverageCondition.TRANSITIONAL_INSURED]", + "tests/test_track_b_insured_status_fix_round_11.py::test_fully_route_refuses_when_recent_credit_proof_does_not_apply[unknown-prior-3-CoverageCondition.EARNED_BASIS]", + "tests/test_track_b_insured_status_fix_round_11.py::test_fully_route_refuses_when_recent_credit_proof_does_not_apply[unknown-prior-3-CoverageCondition.SIMPLIFIED_PRE1951]" + ], + "reproduction_command": "env PYTHONPATH=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/src:/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11 OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round11 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round11 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nfrom populace_dynamics.track_b import insured_status as i\np = Path(i.__file__)\noriginal = p.read_bytes()\nassert hashlib.sha256(original).hexdigest() == 'aebd9223724bc6694e320590a72cd744cb7309dbcb92600bd7ffb11f5d4ca4d1'\nmodified = original.decode()\nbefore = ' if person.conditions & _FULLY_INSURED_ROUTE_CONDITIONS:\\n return True\\n if maximum_qcs < 6:\\n return False\\n'\nafter = ' if maximum_qcs < 6:\\n return False\\n if person.conditions & _FULLY_INSURED_ROUTE_CONDITIONS:\\n return True\\n'\nassert modified.count(before) == 1\nmodified = modified.replace(before, after, 1)\nexec(compile(modified, i.__file__, \"exec\"), i.__dict__)\nimport pytest\nresult = pytest.main(['-q', '-p', 'no:xdist', '-p', 'no:cacheprovider', '--tb=short', 'tests/test_track_b_insured_status_fix_round_11.py::test_fully_route_refuses_when_recent_credit_proof_does_not_apply'])\nassert p.read_bytes() == original\nraise SystemExit(result)\nPY", + "mechanism": "Compile modified module in memory only; source bytes unchanged after execution", + "restored": true, + "open_audit": { + "restricted_opens": 0, + "subprocess.Popen": 0, + "os.system": 0 + } + }, + { + "name": "pre1956_return_above_floor", + "source_sha256": "aebd9223724bc6694e320590a72cd744cb7309dbcb92600bd7ffb11f5d4ca4d1", + "mutated_source_sha256": "f5ba8418f27938547048147fd7276f129d560c2f2883e57f8415103e110019d2", + "changes": [ + { + "before": " if maximum_qcs < 6:\n return False\n if CoverageCondition.DISABILITY_BEFORE_1956 in person.conditions:\n return True\n", + "after": " if CoverageCondition.DISABILITY_BEFORE_1956 in person.conditions:\n return True\n if maximum_qcs < 6:\n return False\n" + } + ], + "command": "env PYTHONPATH=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/src:/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11 OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round11 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round11 TRACKB_ROUND11_MUTATION=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/scratch/review/round-11-mutation-pre1956_return_above_floor.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_11_named.py -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_11.py::test_pre1956_flag_with_blindness_keeps_ordinary_six_qc_floor", + "pytest_arguments": [ + "-q", + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "--tb=short", + "tests/test_track_b_insured_status_fix_round_11.py::test_pre1956_flag_with_blindness_keeps_ordinary_six_qc_floor" + ], + "result": "1 failed, 1 passed in 2.12s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_11.py::test_pre1956_flag_with_blindness_keeps_ordinary_six_qc_floor[3]" + ], + "reproduction_command": "env PYTHONPATH=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/src:/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11 OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round11 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round11 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nfrom populace_dynamics.track_b import insured_status as i\np = Path(i.__file__)\noriginal = p.read_bytes()\nassert hashlib.sha256(original).hexdigest() == 'aebd9223724bc6694e320590a72cd744cb7309dbcb92600bd7ffb11f5d4ca4d1'\nmodified = original.decode()\nbefore = ' if maximum_qcs < 6:\\n return False\\n if CoverageCondition.DISABILITY_BEFORE_1956 in person.conditions:\\n return True\\n'\nafter = ' if CoverageCondition.DISABILITY_BEFORE_1956 in person.conditions:\\n return True\\n if maximum_qcs < 6:\\n return False\\n'\nassert modified.count(before) == 1\nmodified = modified.replace(before, after, 1)\nexec(compile(modified, i.__file__, \"exec\"), i.__dict__)\nimport pytest\nresult = pytest.main(['-q', '-p', 'no:xdist', '-p', 'no:cacheprovider', '--tb=short', 'tests/test_track_b_insured_status_fix_round_11.py::test_pre1956_flag_with_blindness_keeps_ordinary_six_qc_floor'])\nassert p.read_bytes() == original\nraise SystemExit(result)\nPY", + "mechanism": "Compile modified module in memory only; source bytes unchanged after execution", + "restored": true, + "open_audit": { + "restricted_opens": 0, + "subprocess.Popen": 0, + "os.system": 0 + } + }, + { + "name": "deemed_added_to_credit_routes", + "source_sha256": "aebd9223724bc6694e320590a72cd744cb7309dbcb92600bd7ffb11f5d4ca4d1", + "mutated_source_sha256": "cbbcd56be97cf40e2e5d9f337dc5056b210dd4e05561c2f4630196e5ad1c1de2", + "changes": [ + { + "before": " CoverageCondition.MEDICARE_GOVERNMENT_EMPLOYMENT,\n", + "after": " CoverageCondition.MEDICARE_GOVERNMENT_EMPLOYMENT,\n CoverageCondition.DEEMED_FULLY_INSURED,\n" + } + ], + "command": "env PYTHONPATH=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/src:/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11 OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round11 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round11 TRACKB_ROUND11_MUTATION=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/scratch/review/round-11-mutation-deemed_added_to_credit_routes.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_11_named.py -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_11.py::test_no_credit_flag_set_cannot_hide_independently_proved_shortfall", + "pytest_arguments": [ + "-q", + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "--tb=short", + "tests/test_track_b_insured_status_fix_round_11.py::test_no_credit_flag_set_cannot_hide_independently_proved_shortfall" + ], + "result": "1 failed in 3.37s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_11.py::test_no_credit_flag_set_cannot_hide_independently_proved_shortfall" + ], + "reproduction_command": "env PYTHONPATH=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/src:/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11 OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round11 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round11 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nfrom populace_dynamics.track_b import insured_status as i\np = Path(i.__file__)\noriginal = p.read_bytes()\nassert hashlib.sha256(original).hexdigest() == 'aebd9223724bc6694e320590a72cd744cb7309dbcb92600bd7ffb11f5d4ca4d1'\nmodified = original.decode()\nbefore = ' CoverageCondition.MEDICARE_GOVERNMENT_EMPLOYMENT,\\n'\nafter = ' CoverageCondition.MEDICARE_GOVERNMENT_EMPLOYMENT,\\n CoverageCondition.DEEMED_FULLY_INSURED,\\n'\nassert modified.count(before) == 1\nmodified = modified.replace(before, after, 1)\nexec(compile(modified, i.__file__, \"exec\"), i.__dict__)\nimport pytest\nresult = pytest.main(['-q', '-p', 'no:xdist', '-p', 'no:cacheprovider', '--tb=short', 'tests/test_track_b_insured_status_fix_round_11.py::test_no_credit_flag_set_cannot_hide_independently_proved_shortfall'])\nassert p.read_bytes() == original\nraise SystemExit(result)\nPY", + "mechanism": "Compile modified module in memory only; source bytes unchanged after execution", + "restored": true, + "open_audit": { + "restricted_opens": 0, + "subprocess.Popen": 0, + "os.system": 0 + } + }, + { + "name": "simplified_added_to_credit_routes", + "source_sha256": "aebd9223724bc6694e320590a72cd744cb7309dbcb92600bd7ffb11f5d4ca4d1", + "mutated_source_sha256": "79a9d8a124c6a845b99795af0710f66e1440ceef3317088a7605ff489773397c", + "changes": [ + { + "before": " CoverageCondition.MEDICARE_GOVERNMENT_EMPLOYMENT,\n", + "after": " CoverageCondition.MEDICARE_GOVERNMENT_EMPLOYMENT,\n CoverageCondition.SIMPLIFIED_PRE1951,\n" + } + ], + "command": "env PYTHONPATH=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/src:/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11 OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round11 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round11 TRACKB_ROUND11_MUTATION=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/scratch/review/round-11-mutation-simplified_added_to_credit_routes.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_11_named.py -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_11.py::test_no_credit_flag_shortfall_and_exact_minimum_pair", + "pytest_arguments": [ + "-q", + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "--tb=short", + "tests/test_track_b_insured_status_fix_round_11.py::test_no_credit_flag_shortfall_and_exact_minimum_pair" + ], + "result": "2 failed, 30 passed in 3.64s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_11.py::test_no_credit_flag_shortfall_and_exact_minimum_pair[False-42-20-CoverageCondition.SIMPLIFIED_PRE1951]", + "tests/test_track_b_insured_status_fix_round_11.py::test_no_credit_flag_shortfall_and_exact_minimum_pair[False-29-16-CoverageCondition.SIMPLIFIED_PRE1951]" + ], + "reproduction_command": "env PYTHONPATH=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/src:/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11 OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round11 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round11 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nfrom populace_dynamics.track_b import insured_status as i\np = Path(i.__file__)\noriginal = p.read_bytes()\nassert hashlib.sha256(original).hexdigest() == 'aebd9223724bc6694e320590a72cd744cb7309dbcb92600bd7ffb11f5d4ca4d1'\nmodified = original.decode()\nbefore = ' CoverageCondition.MEDICARE_GOVERNMENT_EMPLOYMENT,\\n'\nafter = ' CoverageCondition.MEDICARE_GOVERNMENT_EMPLOYMENT,\\n CoverageCondition.SIMPLIFIED_PRE1951,\\n'\nassert modified.count(before) == 1\nmodified = modified.replace(before, after, 1)\nexec(compile(modified, i.__file__, \"exec\"), i.__dict__)\nimport pytest\nresult = pytest.main(['-q', '-p', 'no:xdist', '-p', 'no:cacheprovider', '--tb=short', 'tests/test_track_b_insured_status_fix_round_11.py::test_no_credit_flag_shortfall_and_exact_minimum_pair'])\nassert p.read_bytes() == original\nraise SystemExit(result)\nPY", + "mechanism": "Compile modified module in memory only; source bytes unchanged after execution", + "restored": true, + "open_audit": { + "restricted_opens": 0, + "subprocess.Popen": 0, + "os.system": 0 + } + }, + { + "name": "military_added_to_raw_earnings", + "source_sha256": "aebd9223724bc6694e320590a72cd744cb7309dbcb92600bd7ffb11f5d4ca4d1", + "mutated_source_sha256": "b07b134dda23019b69ff1e4f5e7ccf6fda8ebd3509fc8480a74d5c80b873e38a", + "changes": [ + { + "before": " CoverageCondition.FISCAL_TAXABLE_YEAR,\n", + "after": " CoverageCondition.FISCAL_TAXABLE_YEAR,\n CoverageCondition.MILITARY_CREDITS,\n" + } + ], + "command": "env PYTHONPATH=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/src:/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11 OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round11 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round11 TRACKB_ROUND11_MUTATION=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/scratch/review/round-11-mutation-military_added_to_raw_earnings.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_11_named.py -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_11.py::test_credit_route_keeps_refusal_even_with_complete_direct_envelope", + "pytest_arguments": [ + "-q", + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "--tb=short", + "tests/test_track_b_insured_status_fix_round_11.py::test_credit_route_keeps_refusal_even_with_complete_direct_envelope" + ], + "result": "4 failed, 8 passed in 6.34s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_11.py::test_credit_route_keeps_refusal_even_with_complete_direct_envelope[zero-42-20-CoverageCondition.MILITARY_CREDITS]", + "tests/test_track_b_insured_status_fix_round_11.py::test_credit_route_keeps_refusal_even_with_complete_direct_envelope[zero-29-16-CoverageCondition.MILITARY_CREDITS]", + "tests/test_track_b_insured_status_fix_round_11.py::test_credit_route_keeps_refusal_even_with_complete_direct_envelope[shortfall-42-20-CoverageCondition.MILITARY_CREDITS]", + "tests/test_track_b_insured_status_fix_round_11.py::test_credit_route_keeps_refusal_even_with_complete_direct_envelope[shortfall-29-16-CoverageCondition.MILITARY_CREDITS]" + ], + "reproduction_command": "env PYTHONPATH=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/src:/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11 OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round11 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round11 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nfrom populace_dynamics.track_b import insured_status as i\np = Path(i.__file__)\noriginal = p.read_bytes()\nassert hashlib.sha256(original).hexdigest() == 'aebd9223724bc6694e320590a72cd744cb7309dbcb92600bd7ffb11f5d4ca4d1'\nmodified = original.decode()\nbefore = ' CoverageCondition.FISCAL_TAXABLE_YEAR,\\n'\nafter = ' CoverageCondition.FISCAL_TAXABLE_YEAR,\\n CoverageCondition.MILITARY_CREDITS,\\n'\nassert modified.count(before) == 1\nmodified = modified.replace(before, after, 1)\nexec(compile(modified, i.__file__, \"exec\"), i.__dict__)\nimport pytest\nresult = pytest.main(['-q', '-p', 'no:xdist', '-p', 'no:cacheprovider', '--tb=short', 'tests/test_track_b_insured_status_fix_round_11.py::test_credit_route_keeps_refusal_even_with_complete_direct_envelope'])\nassert p.read_bytes() == original\nraise SystemExit(result)\nPY", + "mechanism": "Compile modified module in memory only; source bytes unchanged after execution", + "restored": true, + "open_audit": { + "restricted_opens": 0, + "subprocess.Popen": 0, + "os.system": 0 + } + }, + { + "name": "short_taxable_year_dropped_from_raw_earnings", + "source_sha256": "aebd9223724bc6694e320590a72cd744cb7309dbcb92600bd7ffb11f5d4ca4d1", + "mutated_source_sha256": "76a07e4fb29d300d57c1122d26cb2972a856c8a0d618a6cea7e57a2437e57c2a", + "changes": [ + { + "before": " CoverageCondition.SHORT_TAXABLE_YEAR,\n", + "after": "" + } + ], + "command": "env PYTHONPATH=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/src:/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11 OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round11 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round11 TRACKB_ROUND11_MUTATION=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/scratch/review/round-11-mutation-short_taxable_year_dropped_from_raw_earnings.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_11_named.py -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_11.py::test_raw_earnings_flag_preserves_route_only_without_direct_envelope", + "pytest_arguments": [ + "-q", + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "--tb=short", + "tests/test_track_b_insured_status_fix_round_11.py::test_raw_earnings_flag_preserves_route_only_without_direct_envelope" + ], + "result": "2 failed, 4 passed in 2.78s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_11.py::test_raw_earnings_flag_preserves_route_only_without_direct_envelope[42-20-CoverageCondition.SHORT_TAXABLE_YEAR]", + "tests/test_track_b_insured_status_fix_round_11.py::test_raw_earnings_flag_preserves_route_only_without_direct_envelope[29-16-CoverageCondition.SHORT_TAXABLE_YEAR]" + ], + "reproduction_command": "env PYTHONPATH=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/src:/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11 OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round11 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round11 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nfrom populace_dynamics.track_b import insured_status as i\np = Path(i.__file__)\noriginal = p.read_bytes()\nassert hashlib.sha256(original).hexdigest() == 'aebd9223724bc6694e320590a72cd744cb7309dbcb92600bd7ffb11f5d4ca4d1'\nmodified = original.decode()\nbefore = ' CoverageCondition.SHORT_TAXABLE_YEAR,\\n'\nafter = ''\nassert modified.count(before) == 1\nmodified = modified.replace(before, after, 1)\nexec(compile(modified, i.__file__, \"exec\"), i.__dict__)\nimport pytest\nresult = pytest.main(['-q', '-p', 'no:xdist', '-p', 'no:cacheprovider', '--tb=short', 'tests/test_track_b_insured_status_fix_round_11.py::test_raw_earnings_flag_preserves_route_only_without_direct_envelope'])\nassert p.read_bytes() == original\nraise SystemExit(result)\nPY", + "mechanism": "Compile modified module in memory only; source bytes unchanged after execution", + "restored": true, + "open_audit": { + "restricted_opens": 0, + "subprocess.Popen": 0, + "os.system": 0 + } + }, + { + "name": "proof_runs_with_blindness", + "source_sha256": "aebd9223724bc6694e320590a72cd744cb7309dbcb92600bd7ffb11f5d4ca4d1", + "mutated_source_sha256": "245ae0ee2c8bde6fea93cafa34813430d29bf6b06ae15ac6f9f48827e9ab9567", + "changes": [ + { + "before": " not person.statutory_blindness\n and person.prior_disability_periods_provenance\n", + "after": " person.prior_disability_periods_provenance\n" + } + ], + "command": "env PYTHONPATH=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/src:/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11 OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round11 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round11 TRACKB_ROUND11_MUTATION=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/scratch/review/round-11-mutation-proof_runs_with_blindness.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_11_named.py -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_11.py::test_fully_route_refuses_when_recent_credit_proof_does_not_apply", + "pytest_arguments": [ + "-q", + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "--tb=short", + "tests/test_track_b_insured_status_fix_round_11.py::test_fully_route_refuses_when_recent_credit_proof_does_not_apply" + ], + "result": "4 failed, 8 passed in 3.51s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_11.py::test_fully_route_refuses_when_recent_credit_proof_does_not_apply[blind-3-CoverageCondition.DEEMED_FULLY_INSURED]", + "tests/test_track_b_insured_status_fix_round_11.py::test_fully_route_refuses_when_recent_credit_proof_does_not_apply[blind-3-CoverageCondition.TRANSITIONAL_INSURED]", + "tests/test_track_b_insured_status_fix_round_11.py::test_fully_route_refuses_when_recent_credit_proof_does_not_apply[blind-3-CoverageCondition.EARNED_BASIS]", + "tests/test_track_b_insured_status_fix_round_11.py::test_fully_route_refuses_when_recent_credit_proof_does_not_apply[blind-3-CoverageCondition.SIMPLIFIED_PRE1951]" + ], + "reproduction_command": "env PYTHONPATH=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/src:/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11 OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round11 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round11 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nfrom populace_dynamics.track_b import insured_status as i\np = Path(i.__file__)\noriginal = p.read_bytes()\nassert hashlib.sha256(original).hexdigest() == 'aebd9223724bc6694e320590a72cd744cb7309dbcb92600bd7ffb11f5d4ca4d1'\nmodified = original.decode()\nbefore = ' not person.statutory_blindness\\n and person.prior_disability_periods_provenance\\n'\nafter = ' person.prior_disability_periods_provenance\\n'\nassert modified.count(before) == 1\nmodified = modified.replace(before, after, 1)\nexec(compile(modified, i.__file__, \"exec\"), i.__dict__)\nimport pytest\nresult = pytest.main(['-q', '-p', 'no:xdist', '-p', 'no:cacheprovider', '--tb=short', 'tests/test_track_b_insured_status_fix_round_11.py::test_fully_route_refuses_when_recent_credit_proof_does_not_apply'])\nassert p.read_bytes() == original\nraise SystemExit(result)\nPY", + "mechanism": "Compile modified module in memory only; source bytes unchanged after execution", + "restored": true, + "open_audit": { + "restricted_opens": 0, + "subprocess.Popen": 0, + "os.system": 0 + } + }, + { + "name": "proof_runs_with_unknown_prior_history", + "source_sha256": "aebd9223724bc6694e320590a72cd744cb7309dbcb92600bd7ffb11f5d4ca4d1", + "mutated_source_sha256": "59368554c5c5a2a92cc106426d0f22c90cdd2d404bf632929c11053fa3f1610f", + "changes": [ + { + "before": " and person.prior_disability_periods_provenance\n is not EarningsProvenance.UNKNOWN\n", + "after": "" + } + ], + "command": "env PYTHONPATH=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/src:/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11 OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round11 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round11 TRACKB_ROUND11_MUTATION=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/scratch/review/round-11-mutation-proof_runs_with_unknown_prior_history.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_11_named.py -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_11.py::test_fully_route_refuses_when_recent_credit_proof_does_not_apply", + "pytest_arguments": [ + "-q", + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "--tb=short", + "tests/test_track_b_insured_status_fix_round_11.py::test_fully_route_refuses_when_recent_credit_proof_does_not_apply" + ], + "result": "8 failed, 4 passed in 7.16s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_11.py::test_fully_route_refuses_when_recent_credit_proof_does_not_apply[unknown-prior-3-CoverageCondition.DEEMED_FULLY_INSURED]", + "tests/test_track_b_insured_status_fix_round_11.py::test_fully_route_refuses_when_recent_credit_proof_does_not_apply[unknown-prior-3-CoverageCondition.TRANSITIONAL_INSURED]", + "tests/test_track_b_insured_status_fix_round_11.py::test_fully_route_refuses_when_recent_credit_proof_does_not_apply[unknown-prior-3-CoverageCondition.EARNED_BASIS]", + "tests/test_track_b_insured_status_fix_round_11.py::test_fully_route_refuses_when_recent_credit_proof_does_not_apply[unknown-prior-3-CoverageCondition.SIMPLIFIED_PRE1951]", + "tests/test_track_b_insured_status_fix_round_11.py::test_fully_route_refuses_when_recent_credit_proof_does_not_apply[unknown-prior-6-CoverageCondition.DEEMED_FULLY_INSURED]", + "tests/test_track_b_insured_status_fix_round_11.py::test_fully_route_refuses_when_recent_credit_proof_does_not_apply[unknown-prior-6-CoverageCondition.TRANSITIONAL_INSURED]", + "tests/test_track_b_insured_status_fix_round_11.py::test_fully_route_refuses_when_recent_credit_proof_does_not_apply[unknown-prior-6-CoverageCondition.EARNED_BASIS]", + "tests/test_track_b_insured_status_fix_round_11.py::test_fully_route_refuses_when_recent_credit_proof_does_not_apply[unknown-prior-6-CoverageCondition.SIMPLIFIED_PRE1951]" + ], + "reproduction_command": "env PYTHONPATH=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/src:/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11 OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round11 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round11 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nfrom populace_dynamics.track_b import insured_status as i\np = Path(i.__file__)\noriginal = p.read_bytes()\nassert hashlib.sha256(original).hexdigest() == 'aebd9223724bc6694e320590a72cd744cb7309dbcb92600bd7ffb11f5d4ca4d1'\nmodified = original.decode()\nbefore = ' and person.prior_disability_periods_provenance\\n is not EarningsProvenance.UNKNOWN\\n'\nafter = ''\nassert modified.count(before) == 1\nmodified = modified.replace(before, after, 1)\nexec(compile(modified, i.__file__, \"exec\"), i.__dict__)\nimport pytest\nresult = pytest.main(['-q', '-p', 'no:xdist', '-p', 'no:cacheprovider', '--tb=short', 'tests/test_track_b_insured_status_fix_round_11.py::test_fully_route_refuses_when_recent_credit_proof_does_not_apply'])\nassert p.read_bytes() == original\nraise SystemExit(result)\nPY", + "mechanism": "Compile modified module in memory only; source bytes unchanged after execution", + "restored": true, + "open_audit": { + "restricted_opens": 0, + "subprocess.Popen": 0, + "os.system": 0 + } + }, + { + "name": "proof_rejects_exact_minimum", + "source_sha256": "aebd9223724bc6694e320590a72cd744cb7309dbcb92600bd7ffb11f5d4ca4d1", + "mutated_source_sha256": "09d2c494ab04a9de44da6f6b6d1dcb34acaf3e6d6654d195269a45880cf421c7", + "changes": [ + { + "before": " and maximum_qcs < _minimum_current_period_qcs(person)\n", + "after": " and maximum_qcs <= _minimum_current_period_qcs(person)\n" + } + ], + "command": "env PYTHONPATH=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/src:/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11 OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round11 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round11 TRACKB_ROUND11_MUTATION=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/scratch/review/round-11-mutation-proof_rejects_exact_minimum.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_11_named.py -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_11.py::test_no_flag_rejects_declaration_meeting_every_requirement", + "pytest_arguments": [ + "-q", + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "--tb=short", + "tests/test_track_b_insured_status_fix_round_11.py::test_no_flag_rejects_declaration_meeting_every_requirement" + ], + "result": "1 failed in 2.65s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_11.py::test_no_flag_rejects_declaration_meeting_every_requirement" + ], + "reproduction_command": "env PYTHONPATH=/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11/src:/Users/maxghenis/.subfleet/worktrees/20261031-162231-trackb-fix-insured-11 OMP_NUM_THREADS=1 POLARS_MAX_THREADS=1 OMP_WAIT_POLICY=PASSIVE POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round11 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round11 /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - <<'PY'\nfrom pathlib import Path\nimport hashlib\nfrom populace_dynamics.track_b import insured_status as i\np = Path(i.__file__)\noriginal = p.read_bytes()\nassert hashlib.sha256(original).hexdigest() == 'aebd9223724bc6694e320590a72cd744cb7309dbcb92600bd7ffb11f5d4ca4d1'\nmodified = original.decode()\nbefore = ' and maximum_qcs < _minimum_current_period_qcs(person)\\n'\nafter = ' and maximum_qcs <= _minimum_current_period_qcs(person)\\n'\nassert modified.count(before) == 1\nmodified = modified.replace(before, after, 1)\nexec(compile(modified, i.__file__, \"exec\"), i.__dict__)\nimport pytest\nresult = pytest.main(['-q', '-p', 'no:xdist', '-p', 'no:cacheprovider', '--tb=short', 'tests/test_track_b_insured_status_fix_round_11.py::test_no_flag_rejects_declaration_meeting_every_requirement'])\nassert p.read_bytes() == original\nraise SystemExit(result)\nPY", + "mechanism": "Compile modified module in memory only; source bytes unchanged after execution", + "restored": true, + "open_audit": { + "restricted_opens": 0, + "subprocess.Popen": 0, + "os.system": 0 + } + } + ], + "round_11_note": "Eleven deliberate isolated in-memory mutations were caught and discarded. All three new properties bite. Every run audited zero restricted opens or spawned processes and verified original implementation bytes unchanged. The exact commands and standalone reproductions above pin the final formatted source. No committed mutation remains.", + "round_11_final_source_sha256": "aebd9223724bc6694e320590a72cd744cb7309dbcb92600bd7ffb11f5d4ca4d1" } diff --git a/src/populace_dynamics/track_b/insured_status.py b/src/populace_dynamics/track_b/insured_status.py index 3b4c29d12..1cba66c85 100644 --- a/src/populace_dynamics/track_b/insured_status.py +++ b/src/populace_dynamics/track_b/insured_status.py @@ -34,8 +34,10 @@ when every ordinary and possible specialist completion is impossible; assignment-independent minimum-QC proofs precede boundary complexity, skip unknown prior histories and stop at six QCs for blindness. Foreign credits -preserve an unmodeled route after the own-QC floor; no totalized rule is -claimed here. +preserve an unmodeled route before every credit-count proof; no totalization +minimum or eligibility rule is claimed here. Fully-insured-only flags cannot +bypass an independent recent-credit shortfall, but remain possible below six +actual QCs when that proof does not apply. Short DIB-entitled prior periods remain possible. Observable specialist credit alternatives cannot silently produce ordinary-only uninsured answers. The query month is a hypothetical entitlement month, not medical or @@ -122,6 +124,29 @@ class CoverageCondition(Enum): SIMPLIFIED_PRE1951 = "simplified_pre1951" +_FULLY_INSURED_ROUTE_CONDITIONS = frozenset( + { + CoverageCondition.DEEMED_FULLY_INSURED, + CoverageCondition.TRANSITIONAL_INSURED, + CoverageCondition.EARNED_BASIS, + CoverageCondition.SIMPLIFIED_PRE1951, + } +) +_RAW_EARNINGS_CONDITIONS = frozenset( + { + CoverageCondition.RAILROAD_CREDITS, + CoverageCondition.FISCAL_TAXABLE_YEAR, + CoverageCondition.SHORT_TAXABLE_YEAR, + } +) +_CREDIT_ROUTE_CONDITIONS = frozenset( + { + CoverageCondition.MILITARY_CREDITS, + CoverageCondition.MEDICARE_GOVERNMENT_EMPLOYMENT, + } +) + + class InsuredUnsupportedReason(Enum): UNKNOWN_EARNINGS = "unknown_earnings_years_decide_status" UNKNOWN_PERIODS = "unknown_prior_disability_periods_decide_status" @@ -1500,23 +1525,35 @@ def _current_period_start_horizon(person, month): def _flagged_establishment_possible(person, years): - """Overapproximate flagged alternatives to ordinary insurance. - - Final direct QC declarations already supply the credited quarters; - unknown years already permit four. RR annual credits after 1977 use - the ordinary method (RS00301.230/.350). That flag alone cannot add QCs - to this complete direct-QC envelope. - Other specialist declarations are retained rather than adjudicated. + """Preserve flags that can add credits outside the declared envelope. + + Fully-route flags change only the fully insured prerequisite, leaving + 404.130's independent recent-credit rule standing (404.110-.112; + RS00301.101/.106/.470/.475; Act 213(c)). They are handled after that + proof, before the six-QC floor: 404.111 states no numeric minimum. + DISABILITY_BEFORE_1956 replaces the recent test without adding credits + and requires twenty QCs (RS00301.480 A), so it follows both proofs. + + Raw-earnings flags affect compensation or SEI allocation (404.142/.144; + RS00301.220/.340/.350). Final direct QC declarations already supply + their credits, and unknown rows permit four; the I9 direct-credit + contract therefore bounds them. Credit-route flags can add credits + outside those rows: military credits may be freeze-only (404.133; + RS00301.131), and government QCs combine for Medicare (RS00301.160). """ for condition in person.conditions: - if condition is CoverageCondition.RAILROAD_CREDITS and all( + if condition in _RAW_EARNINGS_CONDITIONS and all( row.qc_count is not None or row.qc_quarters is not None or row.provenance is EarningsProvenance.UNKNOWN for row in years.values() ): continue - return True + if ( + condition in _RAW_EARNINGS_CONDITIONS + or condition in _CREDIT_ROUTE_CONDITIONS + ): + return True return False @@ -1587,14 +1624,12 @@ def _could_establish_current_period( for quarter in range(_qid(person.disability_onset), _qid(horizon) + 1) ): return False - if _flagged_establishment_possible(person, years): - return True - if maximum_qcs < 6: - return False - # Foreign coverage is an unmodeled route. After the existing own-QC - # floor, preserve its named refusal without claiming how it qualifies. + # Fixed chronology is independent of the unmodeled foreign route; + # no own-credit count proves impossibility on that route here. if totalization_credits: return True + if _flagged_establishment_possible(person, years): + return True # This proof must precede the alternate's boundary enumeration and # unknown-prior feasibility search: either can otherwise refuse before # an assignment-independent impossibility has been established. @@ -1605,6 +1640,12 @@ def _could_establish_current_period( and maximum_qcs < _minimum_current_period_qcs(person) ): return False + if person.conditions & _FULLY_INSURED_ROUTE_CONDITIONS: + return True + if maximum_qcs < 6: + return False + if CoverageCondition.DISABILITY_BEFORE_1956 in person.conditions: + return True if _pre1956_alternate_possible( person, credits, month, exit_month, lower_credits=lower_credits ): @@ -1759,9 +1800,11 @@ def insured_status( alternate refusal; post-1980 endings can differ under 404.321(c). Establishment is an input error only if no ordinary, observable, or flagged specialist route could validate any completion of the facts. - After the six-QC floor foreign credits preserve an unmodeled route; - no totalized rule is claimed. A conservative minimum-QC proof precedes - boundary complexity, except for blindness and unknown prior history. + Foreign credits preserve an unmodeled route before credit-count proofs; + no totalization minimum or eligibility rule is claimed. A conservative + minimum-QC proof precedes fully-insured-only flags and boundary + complexity, except for blindness and unknown prior history. Fully-route + flags precede the six-QC floor; the pre-1956 flag follows that floor. History validation runs first. Uncomputable QC rows use bounded unknown credits only for this proof; a possible declaration retains its original conversion refusal, including its reason and detail. diff --git a/tests/README-tiers.md b/tests/README-tiers.md index c418ccba2..9c2e664a2 100644 --- a/tests/README-tiers.md +++ b/tests/README-tiers.md @@ -39,9 +39,9 @@ pytest --collect-only -q -m oracle_policyengine | tail -1 | Tier | Tests at HEAD | |---|---:| -| `unit` | 20,748 | +| `unit` | 20,906 | | `artifact` | 4,271 | | `integration_psid` | 1,471 | | `reproduction_legacy` | 520 | | `oracle_policyengine` | 308 | -| **Total** | **27,318** | +| **Total** | **27,476** | diff --git a/tests/test_track_b_insured_status_fix_round_10_proof.py b/tests/test_track_b_insured_status_fix_round_10_proof.py index e7f731a28..27537355c 100644 --- a/tests/test_track_b_insured_status_fix_round_10_proof.py +++ b/tests/test_track_b_insured_status_fix_round_10_proof.py @@ -120,16 +120,12 @@ def test_six_own_qcs_foreign_credits_and_unknown_prior_keep_refusal(): _assert_row(row, i.InsuredUnsupportedReason.TOTALIZATION) -def test_three_own_qcs_and_foreign_credits_still_fail_six_qc_floor(): +def test_three_own_qcs_and_foreign_credits_keep_named_refusal_and_weight(): person = _person() month = date(2001, 1, 1) years = history(person, month, {1999: 3}) - rows = [] - with pytest.raises(i.InvalidFamilyInput, match="no possible insured"): - rows.append( - _evaluate(person, years, month, totalization_credits=("canada",)) - ) - assert count_family_outcomes(rows).rows == 0 + row = _evaluate(person, years, month, totalization_credits=("canada",)) + _assert_row(row, i.InsuredUnsupportedReason.TOTALIZATION) @pytest.mark.parametrize("young", [False, True]) diff --git a/tests/test_track_b_insured_status_fix_round_11.py b/tests/test_track_b_insured_status_fix_round_11.py new file mode 100644 index 000000000..9143e2cdf --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_11.py @@ -0,0 +1,363 @@ +"""Statutory conformance: credit routes and proof-before-refusal ordering. + +Invented declarations only. No population, behavioral, or forecast claim. +The minimum oracle below uses calendar arithmetic and no implementation +helper. Foreign cases claim no totalization minimum or eligibility rule. +""" + +from dataclasses import replace +from datetime import date +from fractions import Fraction + +import pytest +from hypothesis import example, given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as i +from populace_dynamics.track_b.gross_benefits import count_family_outcomes +from tests.test_track_b_insured_status import history + +OBSERVED = i.EarningsProvenance.OBSERVED +UNKNOWN = i.EarningsProvenance.UNKNOWN +WEIGHT = Fraction(11, 5) +FULLY_ROUTES = ( + i.CoverageCondition.DEEMED_FULLY_INSURED, + i.CoverageCondition.TRANSITIONAL_INSURED, + i.CoverageCondition.EARNED_BASIS, + i.CoverageCondition.SIMPLIFIED_PRE1951, +) +RAW_EARNINGS = ( + i.CoverageCondition.RAILROAD_CREDITS, + i.CoverageCondition.FISCAL_TAXABLE_YEAR, + i.CoverageCondition.SHORT_TAXABLE_YEAR, +) +CREDIT_ROUTES = ( + i.CoverageCondition.MILITARY_CREDITS, + i.CoverageCondition.MEDICARE_GOVERNMENT_EMPLOYMENT, +) +RECENT_TEST = i.CoverageCondition.DISABILITY_BEFORE_1956 +NO_ADDED_CREDIT = (*FULLY_ROUTES, *RAW_EARNINGS, RECENT_TEST) +TESTS = (i.InsuredTest.FULLY, i.InsuredTest.DISABILITY) + + +def _person(birth=date(1980, 2, 2), onset=date(2022, 1, 15), **kwargs): + return i.Person( + birth, + disability_onset=onset, + current_disability_period_established=True, + current_disability_period_provenance=OBSERVED, + current_disability_period_end=date(onset.year, 12, 31), + current_disability_period_end_provenance=OBSERVED, + prior_disability_periods_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + **kwargs, + ) + + +def _counts(total, *, last=2021): + """Place final direct QCs in the years immediately preceding onset.""" + result = {} + for year in range(last, last - 10, -1): + result[year], total = min(total, 4), max(0, total - 4) + assert total == 0 + return result + + +def _evaluate(person, years, month, *, test=i.InsuredTest.FULLY, **kwargs): + return i.evaluate_insured_status( + "round-eleven", + WEIGHT, + lambda: i.insured_status(person, years, month, test=test, **kwargs), + ) + + +def _assert_refusal(person, years, month, reason, **kwargs): + row = _evaluate(person, years, month, **kwargs) + assert row.result is None + assert row.unsupported.reason is reason + denominator = count_family_outcomes((row,)) + assert denominator.rows == denominator.unsupported_rows == 1 + assert denominator.weight == denominator.unsupported_weight == WEIGHT + return row + + +def _assert_invalid(person, years, month, **kwargs): + rows = [] + with pytest.raises(i.InvalidFamilyInput, match="no possible insured"): + rows.append(_evaluate(person, years, month, **kwargs)) + denominator = count_family_outcomes(rows) + assert denominator.rows == denominator.unsupported_rows == 0 + assert denominator.weight == denominator.unsupported_weight == 0 + + +def _reason(condition): + return i.InsuredUnsupportedReason[condition.name] + + +@pytest.mark.parametrize("test", TESTS) +@pytest.mark.parametrize("own_qcs", [0, 3, 6, 10]) +@pytest.mark.parametrize( + "month,coverage_end", + [ + (date(2001, 1, 1), None), + (date(2022, 2, 1), None), + (date(2022, 2, 1), date(2000, 12, 1)), + ], + ids=["direct", "age62", "coverage-end"], +) +def test_foreign_credits_refuse_without_an_own_qc_floor( + test, own_qcs, month, coverage_end +): + """Includes Sol's three-QC counterexample and six-QC controls.""" + person = _person(date(1960, 2, 2), date(2000, 1, 15)) + counts = {1998: 3} if own_qcs == 3 else _counts(own_qcs, last=1999) + years = history(person, month, counts, end=coverage_end) + _assert_refusal( + person, + years, + month, + i.InsuredUnsupportedReason.TOTALIZATION, + test=test, + totalization_credits=("canada",), + coverage_end_month=coverage_end, + ) + + +@pytest.mark.parametrize("test", TESTS) +@pytest.mark.parametrize("coverage_end", [None, date(1985, 12, 1)]) +@pytest.mark.parametrize("deemed", [False, True]) +def test_review_recent_credit_shortfall_cannot_be_cured_by_deeming( + test, coverage_end, deemed +): + """Sol's second counterexample and the same case without its flag.""" + person = _person( + date(1924, 1, 2), + date(1985, 1, 15), + conditions=( + (i.CoverageCondition.DEEMED_FULLY_INSURED,) if deemed else () + ), + ) + month = date(1986, 1, 1) + years = history(person, month, {1984: 4, 1985: 2}, end=coverage_end) + _assert_invalid( + person, years, month, test=test, coverage_end_month=coverage_end + ) + + +@pytest.mark.parametrize("condition", list(i.CoverageCondition)) +@pytest.mark.parametrize("foreign", [False, True]) +def test_fixed_overlap_precedes_every_flag_and_foreign_route( + condition, foreign +): + person = _person( + conditions=(condition,), + prior_disability_periods=( + i.DisabilityPeriod(date(2021, 1, 1), date(2022, 1, 14)), + ), + ) + person = replace(person, current_disability_period_end=date(2022, 1, 31)) + month = date(2023, 1, 1) + _assert_invalid( + person, + history(person, month, _counts(20)), + month, + totalization_credits=("canada",) if foreign else (), + ) + + +@pytest.mark.parametrize("condition", NO_ADDED_CREDIT) +@pytest.mark.parametrize("age,minimum", [(42, 20), (29, 16)]) +@pytest.mark.parametrize("meets_minimum", [False, True]) +def test_no_credit_flag_shortfall_and_exact_minimum_pair( + condition, age, minimum, meets_minimum +): + person = _person(birth=date(2022 - age, 2, 2), conditions=(condition,)) + month = date(2023, 1, 1) + total = minimum if meets_minimum else minimum - 1 + years = history(person, month, _counts(total)) + assert sum(row.qc_count or 0 for row in years.values()) == total + if meets_minimum: + _assert_refusal(person, years, month, _reason(condition)) + else: + _assert_invalid(person, years, month) + + +@pytest.mark.parametrize("condition", CREDIT_ROUTES) +@pytest.mark.parametrize("age,minimum", [(42, 20), (29, 16)]) +@pytest.mark.parametrize("total_kind", ["zero", "shortfall", "minimum"]) +def test_credit_route_keeps_refusal_even_with_complete_direct_envelope( + condition, age, minimum, total_kind +): + person = _person(birth=date(2022 - age, 2, 2), conditions=(condition,)) + month = date(2023, 1, 1) + total = {"zero": 0, "shortfall": minimum - 1, "minimum": minimum}[ + total_kind + ] + _assert_refusal( + person, + history(person, month, _counts(total)), + month, + _reason(condition), + ) + + +@pytest.mark.parametrize("condition", FULLY_ROUTES) +@pytest.mark.parametrize( + "exception,total", + [("blind", 3), ("unknown-prior", 3), ("unknown-prior", 6)], +) +def test_fully_route_refuses_when_recent_credit_proof_does_not_apply( + condition, exception, total +): + person = _person(conditions=(condition,)) + if exception == "blind": + person = replace(person, statutory_blindness=True) + else: + person = replace(person, prior_disability_periods_provenance=UNKNOWN) + month = date(2023, 1, 1) + _assert_refusal( + person, + history(person, month, _counts(total)), + month, + _reason(condition), + ) + + +@pytest.mark.parametrize("total", [3, 20]) +def test_pre1956_flag_with_blindness_keeps_ordinary_six_qc_floor(total): + person = _person(statutory_blindness=True, conditions=(RECENT_TEST,)) + month = date(2023, 1, 1) + years = history(person, month, _counts(total)) + if total < 6: + _assert_invalid(person, years, month) + else: + _assert_refusal(person, years, month, _reason(RECENT_TEST)) + + +@pytest.mark.parametrize("condition", RAW_EARNINGS) +@pytest.mark.parametrize("age,minimum", [(42, 20), (29, 16)]) +def test_raw_earnings_flag_preserves_route_only_without_direct_envelope( + condition, age, minimum +): + person = _person(birth=date(2022 - age, 2, 2), conditions=(condition,)) + month = date(2023, 1, 1) + years = history(person, month, _counts(minimum - 1)) + _assert_invalid(person, years, month) + years[2010] = i.CoverageYear(OBSERVED, wages=Fraction(0)) + _assert_refusal(person, years, month, _reason(condition)) + + +FLAG_PAIRS = ( + (FULLY_ROUTES[0], RECENT_TEST), + (FULLY_ROUTES[0], RAW_EARNINGS[0]), + (FULLY_ROUTES[0], CREDIT_ROUTES[0]), + (RECENT_TEST, RAW_EARNINGS[0]), + (RECENT_TEST, CREDIT_ROUTES[0]), + (RAW_EARNINGS[0], CREDIT_ROUTES[0]), +) + + +@pytest.mark.parametrize("conditions", FLAG_PAIRS) +@pytest.mark.parametrize("total", [6, 20]) +def test_two_flag_classes_preserve_each_independent_route(conditions, total): + person = _person(conditions=conditions) + month = date(2023, 1, 1) + years = history(person, month, _counts(total)) + if total < 20 and not set(conditions).intersection(CREDIT_ROUTES): + _assert_invalid(person, years, month) + else: + first = min(conditions, key=lambda condition: condition.value) + _assert_refusal(person, years, month, _reason(first)) + + +@settings(max_examples=48, deadline=None) +@example(total=0, age=22, blind=False, condition=None) +@example(total=3, age=42, blind=True, condition=FULLY_ROUTES[0]) +@given( + total=st.integers(0, 40), + age=st.sampled_from([22, 29, 31, 42]), + blind=st.booleans(), + condition=st.one_of(st.none(), st.sampled_from(list(i.CoverageCondition))), +) +def test_foreign_credit_refusal_is_independent_of_own_qc_count( + total, age, blind, condition +): + person = _person( + birth=date(2022 - age, 2, 2), + statutory_blindness=blind, + conditions=() if condition is None else (condition,), + ) + month = date(2023, 1, 1) + _assert_refusal( + person, + history(person, month, _counts(total)), + month, + i.InsuredUnsupportedReason.TOTALIZATION, + totalization_credits=("invented-foreign-credit",), + ) + + +def _independent_recent_minimum(age): + """404.130: twenty, or half elapsed quarters after age 21, floor six. + + Birth is always February 2 and onset January 15, 2022. Attainment is + February 1; quarter arithmetic here is deliberately independent of + the insured-status implementation. There are no prior periods. + """ + birth_year = 2022 - age + onset_quarter = 2022 * 4 + age31_quarter = (birth_year + 31) * 4 + if onset_quarter >= age31_quarter: + return 20 + first_elapsed_quarter = (birth_year + 21) * 4 + 1 + elapsed = onset_quarter - first_elapsed_quarter + 1 + return min(20, max(6, elapsed // 2)) + + +@settings(max_examples=64, deadline=None) +@example(age=42, missing=1, conditions=frozenset((FULLY_ROUTES[0],))) +@example(age=29, missing=1, conditions=frozenset((RAW_EARNINGS[2],))) +@given( + age=st.sampled_from([22, 24, 29, 31, 42]), + missing=st.integers(1, 20), + conditions=st.sets(st.sampled_from(NO_ADDED_CREDIT), min_size=1), +) +def test_no_credit_flag_set_cannot_hide_independently_proved_shortfall( + age, missing, conditions +): + required = _independent_recent_minimum(age) + total = max(0, required - missing) + assert total < required + person = _person(birth=date(2022 - age, 2, 2), conditions=conditions) + month = date(2023, 1, 1) + _assert_invalid(person, history(person, month, _counts(total)), month) + + +@settings(max_examples=36, deadline=None) +@example(age=29, extra=0, condition=RAW_EARNINGS[2]) +@given( + age=st.sampled_from([22, 24, 29, 31, 42]), + extra=st.integers(0, 10), + condition=st.sampled_from(list(i.CoverageCondition)), +) +def test_no_flag_rejects_declaration_meeting_every_requirement( + age, extra, condition +): + required = _independent_recent_minimum(age) + person = _person(birth=date(2022 - age, 2, 2)) + month = date(2023, 1, 1) + years = history(person, month, _counts(required + extra)) + baseline = _evaluate(person, years, month) + assert baseline.result is not None + assert baseline.unsupported is None + denominator = count_family_outcomes((baseline,)) + assert denominator.rows == 1 + assert denominator.weight == WEIGHT + assert denominator.unsupported_rows == denominator.unsupported_weight == 0 + _assert_refusal( + replace(person, conditions=(condition,)), + years, + month, + _reason(condition), + ) diff --git a/tests/test_track_b_insured_status_fix_round_3_validation.py b/tests/test_track_b_insured_status_fix_round_3_validation.py index 5eb7092d8..20a7fe349 100644 --- a/tests/test_track_b_insured_status_fix_round_3_validation.py +++ b/tests/test_track_b_insured_status_fix_round_3_validation.py @@ -61,19 +61,37 @@ def test_impossible_establishment_creates_no_evaluator_denominator_row(): def test_impossible_unknown_history_validation_precedes_coverage_refusal(): person = replace( - _impossible_person(), + _impossible_person(date(2022, 1, 15)), + prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, + prior_disability_periods=( + i.DisabilityPeriod(date(2021, 1, 1), date(2022, 12, 31)), + ), + current_disability_period_end=date(2022, 12, 31), + current_disability_period_end_provenance=i.EarningsProvenance.OBSERVED, conditions=(i.CoverageCondition.RAILROAD_CREDITS,), ) month = date(2029, 4, 1) - # Three own QCs cannot pass the floor even when foreign coverage is - # declared. Six own QCs leave that unmodeled route unresolved. + years = history(person, month, {2028: 3}) + years[2020] = i.CoverageYear(i.EarningsProvenance.UNKNOWN) + # No credit route can remove the declared prior quarters or move the + # current start outside its fixed onset/end interval. + rows = [] with pytest.raises(i.InvalidFamilyInput): - i.insured_status( - person, - history(person, month, {2028: 3}), - month, - totalization_credits=("invented-foreign-credit",), + rows.append( + i.evaluate_insured_status( + "fixed-overlap-before-foreign-refusal", + Fraction(11, 5), + lambda: i.insured_status( + person, + years, + month, + totalization_credits=("invented-foreign-credit",), + ), + ) ) + denominator = count_family_outcomes(rows) + assert denominator.rows == denominator.unsupported_rows == 0 + assert denominator.weight == denominator.unsupported_weight == 0 @settings(max_examples=20, deadline=None) diff --git a/tests/test_track_b_insured_status_fix_round_5_possibility.py b/tests/test_track_b_insured_status_fix_round_5_possibility.py index f506d3851..057bf39e1 100644 --- a/tests/test_track_b_insured_status_fix_round_5_possibility.py +++ b/tests/test_track_b_insured_status_fix_round_5_possibility.py @@ -61,6 +61,9 @@ def _classification(person, years, month): ) except i.InvalidFamilyInput: assert not rows + denominator = count_family_outcomes(rows) + assert denominator.rows == denominator.unsupported_rows == 0 + assert denominator.weight == denominator.unsupported_weight == 0 return False denominator = count_family_outcomes(rows) assert denominator.rows == 1 @@ -218,40 +221,128 @@ def test_exact_classification_keeps_automatic_and_every_flagged_route( assert _assert_exact_classification(person, years, month) == [True] * 16 -@pytest.mark.parametrize("condition", list(i.CoverageCondition)) -def test_exact_classification_keeps_each_independent_flagged_route(condition): - if condition is i.CoverageCondition.RAILROAD_CREDITS: - person = i.Person( - date(1930, 2, 2), - disability_onset=date(1952, 7, 15), - prior_disability_periods_provenance=OBSERVED, - current_disability_period_established=True, - current_disability_period_provenance=OBSERVED, - current_disability_period_end=date(1952, 9, 30), - current_disability_period_end_provenance=OBSERVED, - sspa211_applies=False, - sspa211_provenance=OBSERVED, - conditions=(condition,), - ) - month = date(1968, 2, 1) - years = history(person, month) - # Ordinary wages are known; separately flagged RR compensation - # is unresolved, so these are not final credited-QC declarations. - years[1950] = i.CoverageYear( - OBSERVED, quarterly_wages=(Fraction(0),) * 4 - ) - years[1953] = i.CoverageYear(UNKNOWN) - expected_fillings = 16 - else: - person, years, month = _fixed_end_case() - person = replace(person, conditions=(condition,)) - expected_fillings = 5 +@pytest.mark.parametrize( + "condition", + [ + i.CoverageCondition.RAILROAD_CREDITS, + i.CoverageCondition.FISCAL_TAXABLE_YEAR, + i.CoverageCondition.SHORT_TAXABLE_YEAR, + ], +) +def test_exact_classification_keeps_raw_earnings_flagged_routes(condition): + person = i.Person( + date(1930, 2, 2), + disability_onset=date(1952, 7, 15), + prior_disability_periods_provenance=OBSERVED, + current_disability_period_established=True, + current_disability_period_provenance=OBSERVED, + current_disability_period_end=date(1952, 9, 30), + current_disability_period_end_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + conditions=(condition,), + ) + month = date(1968, 2, 1) + years = history(person, month) + # The raw amounts leave the separately flagged credit allocation + # unresolved; these are not final credited-QC declarations. + years[1950] = i.CoverageYear(OBSERVED, quarterly_wages=(Fraction(0),) * 4) + years[1953] = i.CoverageYear(UNKNOWN) upper = {year: i._credits(year, row, True) for year, row in years.items()} assert not i._pre1956_alternate_possible(person, upper, month, None) - assert ( - _assert_exact_classification(person, years, month) - == [True] * expected_fillings + assert _assert_exact_classification(person, years, month) == [True] * 16 + + +@pytest.mark.parametrize( + "condition", + [ + i.CoverageCondition.MILITARY_CREDITS, + i.CoverageCondition.MEDICARE_GOVERNMENT_EMPLOYMENT, + ], +) +def test_exact_classification_keeps_independent_credit_routes(condition): + person, years, month = _fixed_end_case() + person = replace(person, conditions=(condition,)) + upper = {year: i._credits(year, row, True) for year, row in years.items()} + assert not i._pre1956_alternate_possible(person, upper, month, None) + assert _assert_exact_classification(person, years, month) == [True] * 5 + + +def _flagged_minimum_case(condition, *, young, shortfall): + onset_year = 1985 if young else 2000 + person = i.Person( + date(1960, 2, 2), + disability_onset=date(onset_year, 1, 15), + prior_disability_periods_provenance=OBSERVED, + current_disability_period_established=True, + current_disability_period_provenance=OBSERVED, + current_disability_period_end=date(onset_year, 12, 31), + current_disability_period_end_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + conditions=(condition,), ) + month = date(onset_year + 1, 1, 1) + counts = {onset_year - 2: 4 - shortfall} + if not young: + counts.update( + {year: 4 for year in range(onset_year - 5, onset_year - 2)} + ) + years = history(person, month, counts) + years[onset_year - 1] = i.CoverageYear(UNKNOWN) + return person, years, month + + +@pytest.mark.parametrize( + "condition", + [ + i.CoverageCondition.DEEMED_FULLY_INSURED, + i.CoverageCondition.TRANSITIONAL_INSURED, + i.CoverageCondition.EARNED_BASIS, + i.CoverageCondition.SIMPLIFIED_PRE1951, + i.CoverageCondition.DISABILITY_BEFORE_1956, + i.CoverageCondition.RAILROAD_CREDITS, + i.CoverageCondition.FISCAL_TAXABLE_YEAR, + i.CoverageCondition.SHORT_TAXABLE_YEAR, + ], +) +@pytest.mark.parametrize("young", [False, True]) +@pytest.mark.parametrize("shortfall", [False, True]) +def test_exact_classification_bounds_flags_that_add_no_declared_credit( + condition, young, shortfall +): + person, years, month = _flagged_minimum_case( + condition, young=young, shortfall=shortfall + ) + # The recent-credit minima are twenty QCs and, for this under31 + # fixture, half of sixteen elapsed quarters: eight QCs. Each direct + # envelope enumerates every annual filling, including the threshold. + expected = [False] * 5 if shortfall else [False] * 4 + [True] + assert _assert_exact_classification(person, years, month) == expected + if not shortfall: + concrete = { + **years, + person.disability_onset.year - 1: declared(4), + } + row = i.evaluate_insured_status( + "flagged-minimum-refusal", + Fraction(3, 2), + lambda: i.insured_status( + person, concrete, month, test=i.InsuredTest.FULLY + ), + ) + assert row.result is None + assert ( + row.unsupported.reason + is i.InsuredUnsupportedReason[condition.name] + ) + denominator = count_family_outcomes((row,)) + assert denominator.rows == denominator.unsupported_rows == 1 + assert ( + denominator.weight + == denominator.unsupported_weight + == Fraction(3, 2) + ) def test_exact_classification_keeps_short_dib_entitled_prior_filling(): diff --git a/tests/test_track_b_insured_status_period_declarations.py b/tests/test_track_b_insured_status_period_declarations.py index 7a761c1f2..655011f3b 100644 --- a/tests/test_track_b_insured_status_period_declarations.py +++ b/tests/test_track_b_insured_status_period_declarations.py @@ -5,11 +5,15 @@ from dataclasses import replace from datetime import date +from fractions import Fraction import pytest from populace_dynamics.track_b import insured_status as i -from populace_dynamics.track_b.gross_benefits import InvalidFamilyInput +from populace_dynamics.track_b.gross_benefits import ( + InvalidFamilyInput, + count_family_outcomes, +) from tests.test_track_b_insured_status import history @@ -54,7 +58,7 @@ def test_established_current_period_with_unknown_prior_periods_uses_bounds(): assert concrete.current_disability_period_start == date(2022, 4, 1) assert disability.dli.lower <= concrete.dli.lower <= disability.dli.upper - # No established period can overcome the universal six-QC minimum. + # Without foreign credits, these ordinary declarations lack six QCs. with pytest.raises(InvalidFamilyInput): i.insured_status( person, @@ -63,19 +67,38 @@ def test_established_current_period_with_unknown_prior_periods_uses_bounds(): test=i.InsuredTest.FULLY, ) - for foreign_credits, conditions in ( - (("invented-foreign-credit",), frozenset()), - ((), frozenset({i.CoverageCondition.RAILROAD_CREDITS})), - ): - invalid_person = replace(person, conditions=conditions) - with pytest.raises(InvalidFamilyInput): - i.insured_status( - invalid_person, - history(invalid_person, month), - month, - test=i.InsuredTest.FULLY, - totalization_credits=foreign_credits, - ) + foreign_row = i.evaluate_insured_status( + "unknown-prior-foreign-credits", + Fraction(11, 5), + lambda: i.insured_status( + person, + history(person, month), + month, + test=i.InsuredTest.FULLY, + totalization_credits=("invented-foreign-credit",), + ), + ) + assert foreign_row.result is None + assert ( + foreign_row.unsupported.reason + is i.InsuredUnsupportedReason.TOTALIZATION + ) + denominator = count_family_outcomes((foreign_row,)) + assert denominator.rows == denominator.unsupported_rows == 1 + assert ( + denominator.weight == denominator.unsupported_weight == Fraction(11, 5) + ) + + railroad_person = replace( + person, conditions=(i.CoverageCondition.RAILROAD_CREDITS,) + ) + with pytest.raises(InvalidFamilyInput): + i.insured_status( + railroad_person, + history(railroad_person, month), + month, + test=i.InsuredTest.FULLY, + ) def test_unknown_earnings_deciding_established_current_start_refuse_by_name(): diff --git a/tests/test_track_b_insured_status_sources.py b/tests/test_track_b_insured_status_sources.py index b09080929..3ae7a1dc3 100644 --- a/tests/test_track_b_insured_status_sources.py +++ b/tests/test_track_b_insured_status_sources.py @@ -57,6 +57,7 @@ def source_text(source_id): "poms_rs_00301_101": [ "For certain benefits, the QCs must be earned within a specific " "time frame.", + "Transitional Insured Status", ], "poms_rs_00301_102": [ "Section 211 of the SSPA applies to an alien worker whose Social " @@ -81,6 +82,7 @@ def source_text(source_id): "poms_rs_00301_106": [ "Do not use QCs earned before 01/01/84 for deemed fully insured " "status.", + "deemed fully insured for all title II purposes", ], "poms_rs_00301_107": [ "Contact the employer to establish that deemed fully insured " @@ -153,6 +155,8 @@ def source_text(source_id): "poms_rs_00301_160": [ "Meeting the requirements for a freeze only is not sufficient " "to qualify for Medicare.", + "Use GEQCs, DQCs, and regular QCs to establish the insured status " + "requirements for Medicare purposes.", ], "poms_rs_00301_161": [ "The reduction is effective 01/94 or, if later, the month after " @@ -168,6 +172,8 @@ def source_text(source_id): "poms_rs_00301_220": [ "the number of months in each calendar year that are completely " "included within the taxable year.", + "we will allocate the SEI proportionately to the two calendars " + "years", ], "poms_rs_00301_230": [ "Assignment of QCs is flexible.", @@ -216,6 +222,7 @@ def source_text(source_id): ], "poms_rs_00301_340": [ "We credit SEI equally to each quarter of the calendar year.", + "credit SEI equally to the calendar quarter in which the TY ends", ], "poms_rs_00301_345": [ "If a number holder (NH) has maximum creditable earnings in a " @@ -225,6 +232,8 @@ def source_text(source_id): "poms_rs_00301_350": [ "The Railroad Retirement Act contains a table for computing " "compensation for QCs before 1978.", + "we may use RR compensation in determining the number of " + "quarters of coverage (QCs)", ], "poms_rs_00301_470": [ "a WWII veteran who separated from active military service " @@ -235,11 +244,14 @@ def source_text(source_id): "Any wages reallocated based on wages earned cannot then be " "used to establish a QC based on wages paid for the same year " "or any subsequent year.", + "fully insured status could be established by crediting certain " + "wages on an earned rather than a paid basis", ], "poms_rs_00301_480": [ "It is also not effective for disabilities beginning after " "1955, as any NH disabled after 1955 and meeting the " "alternative test would be insured under the 20/40 rule.", + "at least 20 quarters of coverage (QC) by the end of that quarter", ], "poms_rs_00301_600": [ "The election of coverage by a religious order under the " @@ -251,6 +263,9 @@ def source_text(source_id): ], "ecfr_20cfr404_subpart_b": [ "You reach a particular age on the day before your birthday.", + "you must meet one of these rules and you must be fully insured", + "For purposes of establishing a period of disability only, " + "we give you quarters of coverage", "You are fully insured as of the first day of the calendar " "quarter in which you acquire the last needed QC", "we do not count as an elapsed year any year which is wholly or " @@ -317,6 +332,7 @@ def source_text(source_id): "for which you received benefits.", ], "lii_usc_42_413": [ + "For purposes of sections 414(a) and 415(d)", "with such product, if not a multiple of $10, being rounded " "to the next higher multiple of $10 where such amount is a " "multiple of $5 but not of $10 and to the nearest multiple " diff --git a/tests/tier_counts.json b/tests/tier_counts.json index d20d5b876..1cf03c498 100644 --- a/tests/tier_counts.json +++ b/tests/tier_counts.json @@ -1,7 +1,7 @@ { "schema_version": 1, "counts": { - "unit": 20748, + "unit": 20906, "artifact": 4271, "integration_psid": 1471, "reproduction_legacy": 520, From a0162b3ef647a9ca2562c6e700e7bd44de8849f0 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sat, 31 Oct 2026 16:59:47 -0400 Subject: [PATCH 17/46] Stop flags from hiding an empty recent window (#562 round 12) Round 11 left one gap. 20 old QCs with every recent window empty still counted a row under a fully-route flag, because the proof compared lifetime QCs with the requirement and the flag's return ran before the ordinary scan. 404.130(a) needs one of the four rules "and you must be fully insured", and a fully-route flag changes only the second half. _recent_rule_possible now scans each candidate quarter from onset through the horizon under upper credits, without the fully insured prerequisite, and a fully-route flag keeps its refusal only if some quarter meets a recent rule, the automatic pre-1956 alternate stays open, or blindness or UNKNOWN prior history blocks the proof. A complexity refusal in the scan keeps the flag's own reason. The scan and the fixed overlap check share one prior-period predicate. DISABILITY_BEFORE_1956 no longer returns early. RS 00301.480 B.1 ends the route at 12/31/55, and the flag adds nothing the automatic alternate lacks, so an onset in 2000 with old QCs is now InvalidFamilyInput. The rule still doesn't test a flag's own conditions. Adds 65 tests, with independent recent and alternate oracles, and ten caught mutations. No existing test changed. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 170 +++-- .../track_b_insured_status_mutations.json | 354 +++++++++- .../track_b/insured_status.py | 89 ++- tests/README-tiers.md | 4 +- ...est_track_b_insured_status_fix_round_12.py | 662 ++++++++++++++++++ tests/tier_counts.json | 2 +- 6 files changed, 1205 insertions(+), 76 deletions(-) create mode 100644 tests/test_track_b_insured_status_fix_round_12.py diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index d661dc427..fe055f5c4 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -125,7 +125,9 @@ possibility retains its named refusal. The automatically observable alternate-pre1956 scan independently obeys the same immutable start horizon. The first permitted alternate start is July 1, 1952 (RS .480 B.1). An earlier fixed start horizon cannot be rescued by that later witness. -Explicit specialist declarations remain separately preserved. +An explicit `DISABILITY_BEFORE_1956` declaration supplies no route beyond +that automatic alternate. Other specialist declarations retain only the +possibilities allowed by their flag classes below. The captured 404.321(b), headed "When disability ended before December 1, 1980", says: @@ -225,11 +227,9 @@ After the fixed-quarter overlap check, declared foreign credits preserve their unmodeled route before every credit-count proof. Credit-route flags, or raw-earnings flags without a complete direct-QC envelope, do likewise. The flag classes and their captured premises are listed below. The -minimum-requirement proof then precedes fully-route flags, the ordinary -six-QC floor, the declared pre1956 alternate, and every automatic alternate -scan, boundary enumeration, or UNKNOWN-prior-history feasibility scan. -The proof runs only with known prior history and without statutory -blindness. Every +minimum-requirement proof precedes every recent-rule or alternate scan, +boundary enumeration, and UNKNOWN-prior-history feasibility scan. It runs +only with known prior history and without statutory blindness. Every remaining ordinary 20/40 or alternate route needs 20 QCs. If the earliest candidate start permits the under-31 or subsequent-special rule, the proof also takes that rule's requirement after removing every prior-period @@ -245,10 +245,29 @@ lower bound too high (404.130(a)–(f); RS .480 A). Blindness uses the fully insured prerequisite alone (`blindness_fully_only`), so it disables the stronger proof. UNKNOWN prior history can supply additional exclusions and also disables that proof. A fully-route flag -then preserves its named refusal even below six actual QCs: its unmodeled -fully insured rule may replace that ordinary prerequisite. The pre1956 -alternate changes the recent test but still requires 20 QCs (RS .480 A), -so its explicit flag remains below the ordinary six-QC floor. +preserves its named refusal in either case, even below six actual QCs: +its unmodeled fully insured rule may replace that ordinary prerequisite. +With known prior history and no blindness, the flag instead needs a +possible recent rule in a nonoverlapping starting quarter from onset +through the immutable horizon, or a possible automatic pre1956 alternate. +The recent scan uses the same assignment, all-period use/disregard, and +special-window rules as the ordinary witness, relaxing only its fully +insured prerequisite (404.130(a)–(d), (f)). If maximum feasible credits +cannot satisfy any such recent rule and the alternate is unavailable, no +lower-credit filling can establish the period. A fully-route flag changes +neither constraint. A complexity refusal during this scan preserves +possibility so that the flag retains its own named refusal. + +Without a fully-route flag, the ordinary six-QC floor still precedes the +automatic alternate. The pre1956 alternate needs 20 QCs (RS .480 A) and +an eligible start no later than December 31, 1955 (RS .480 B.1). Its +explicit flag adds no credit, condition, or route beyond the automatic +check and therefore supplies no separate early return. Any declaration +that survives establishment validation still receives the flag's named +refusal. The rule does not test a flag's own conditions: for example, a +`DEEMED_FULLY_INSURED` declaration stays a declared fact even for a birth +year outside 404.112's nonprofit-worker condition. These proofs determine +only whether that fact could supply the missing prerequisite. Declared foreign credits receive `totalization_credits_unsupported`, with their evaluator row and weight, for zero, three, six, or ten own QCs once @@ -568,13 +587,21 @@ every raw row. The establishment possibility checks then precede coverage refusals. Within those checks, fixed-quarter overlap comes first, followed by declared foreign credits and any credit-route flag or raw-earnings flag without a complete direct-QC envelope. The known-history nonblind -minimum-requirement proof follows. Next come fully-route flags, the -ordinary six-QC floor, the declared pre1956 alternate, and the automatic -alternate route. Only then can boundary assignments, UNKNOWN -prior-history feasibility, or concrete earnings fillings be enumerated. -Neither `_unknown_prior_history_is_empty` nor an alternate-path -`_boundary_variants` call can run ahead of the applicable proof. Before -that proof, raw conversion can encounter only four reachable refusals: `qc_amount_year_unsupported`, +minimum-requirement proof follows before every boundary enumeration. +A fully-route flag then preserves possibility immediately for blindness +or UNKNOWN prior history. Without that flag, fewer than six maximum QCs +proves impossibility. Otherwise a fully-route flag needs a recent-rule +witness from onset through the horizon, or the automatic pre1956 +alternate. Neither route means impossibility even with that flag. An +explicit `DISABILITY_BEFORE_1956` flag supplies no separate route or early +return. The remaining ordinary boundary assignments, UNKNOWN prior-history +feasibility, and concrete earnings fillings follow unchanged. Neither +`_unknown_prior_history_is_empty` nor an alternate-path +`_boundary_variants` call can run ahead of the minimum-requirement proof. +A complexity refusal in the fully-route recent scan preserves possibility, +so it does not replace the declared flag's own refusal reason. Raw +conversion, before the establishment proofs, can encounter only four +reachable refusals: `qc_amount_year_unsupported`, `1937_earnings_allocation_unsupported`, `pre1955_agricultural_allocation_unsupported`, and `pre1951_self_employment_unsupported`. These are deferred while possibility @@ -628,7 +655,10 @@ declaration survives every applicable impossibility proof. The following table supplies the classification premises used by those proofs. Section 404.130(a) requires one of its four rules "and you must be fully insured"; a rule changing only fully insured status cannot supply missing recent -credits. This classification does not adjudicate the flagged rules. +credits. This classification does not adjudicate the flagged rules or +test whether a flag's own conditions are met. In particular, an otherwise +unreachable 404.112 birth cohort does not invalidate an explicitly declared +`DEEMED_FULLY_INSURED` fact. | Flag | Captured premise and effect | Class | | --- | --- | --- | @@ -636,7 +666,7 @@ credits. This classification does not adjudicate the flagged rules. | `TRANSITIONAL_INSURED` | RS .101 B.1 lists "Transitional Insured Status" beside fully insured status for spouse benefits. It is absent from 404.130's four rules and supplies no recent QC. | Fully route | | `EARNED_BASIS` | RS .475 A says "fully insured status could be established by crediting certain wages on an earned rather than a paid basis". Its stated special method changes the fully insured prerequisite. | Fully route | | `SIMPLIFIED_PRE1951` | Act 213(c) says "For purposes of sections 414(a) and 415(d)"; 404.110(d)(1) says "For purposes of paragraph (b) of this section". Simplified credits affect fully insured status, not the independent recent test. | Fully route | -| `DISABILITY_BEFORE_1956` | RS .480 A requires "at least 20 quarters of coverage (QC) by the end of that quarter". The alternate replaces the recent test and supplies no additional QC. | Recent test | +| `DISABILITY_BEFORE_1956` | RS .480 A requires "at least 20 quarters of coverage (QC) by the end of that quarter", the continuous-QC clock, and an eligible historical start; B.1 says "the last day on which it can begin is 12/31/55". The flag adds no credit or route beyond the automatic alternate check. A surviving declaration retains its named refusal. | Recent test | | `RAILROAD_CREDITS` | RS .350 A says "we may use RR compensation in determining the number of quarters of coverage (QCs)"; RS .131 also identifies freeze credits. Compensation can add QCs before a final direct-QC declaration. | Raw earnings | | `FISCAL_TAXABLE_YEAR` | RS .220 says "we will allocate the SEI proportionately to the two calendars years"; 404.142 and .144 govern taxable-year allocation. The rule acts on earnings, not an already declared final QC count. | Raw earnings | | `SHORT_TAXABLE_YEAR` | RS .340 B.2.b says "credit SEI equally to the calendar quarter in which the TY ends" and preceding quarters in the taxable year; 404.142 and .144 govern allocation. | Raw earnings | @@ -648,10 +678,14 @@ is a direct `qc_count`, direct `qc_quarters`, or UNKNOWN row. I9's direct-credit contract then already fixes or bounds the final credits; raw-amount allocation cannot add credits outside it. Military credits are excluded from that contract because 404.133 expressly gives freeze-only -credits. Fully-route flags remain below the recent-credit proof but above -the ordinary six-QC floor. Their named refusals survive blindness or -UNKNOWN prior history, which disable the proof, and any case meeting the -minimum. The pre1956 flag remains below that floor because it needs 20 QCs. +credits. Fully-route flags remain below the numerical recent-credit proof +and, with known prior history and no blindness, the candidate-quarter +recent scan. They bypass only the ordinary fully insured prerequisite and +its six-QC floor. Their named refusals survive blindness or UNKNOWN prior +history, where the recent proof is inapplicable, and any case with a +possible recent or automatic alternate route. The pre1956 flag still obeys +the ordinary six-QC floor and automatic alternate conditions because it +adds no credit or route. Automatic detection additionally applies where the ordinary declarations reveal a potentially decisive specialist route: @@ -670,7 +704,7 @@ allocation or adjudicate application facts. | Condition | Observable trigger or absent fact | | --- | --- | | `SIMPLIFIED_PRE1951` | Raw 1937–1950 quarterly wages provide an aggregate divided by $400; post1950 upper QCs and the fully insured prerequisite bound whether it could decide status (213(c); 404.110(d); RS .315). UNKNOWN pre1951 years can supply unbounded raw wages and therefore also trigger the refusal. Direct `qc_quarters` declare credited quarters rather than raw wages. The simplified method does not apply to a disability claim. Filing, retroactivity, and section 227 facts remain unmodeled. | -| `DISABILITY_BEFORE_1956` | Medical onset and QCs reveal a possible RS .480 alternative: at least 20 total QCs and every counted quarter from 1951Q1 through the quarter before a qualifying 1952Q3–1955Q4 candidate quarter at or after onset, with at least six such quarters, under favorable all-period use or disregard (RS .132 B.2, C.2). For declared current establishment, that candidate must fit the immutable declared-end/continuity/death/FRA horizon. RS .480 A excludes the route when the lower-credit filling has 20/40 in the rule's disabled-quarter scan before October 1960; if only some fillings do, the alternate remains possible. Refuse automatically when this could change a failed disability predicate. Application conditions remain unmodeled. | +| `DISABILITY_BEFORE_1956` | The explicit flag adds no route beyond this automatic check. Medical onset and QCs reveal a possible RS .480 alternative: at least 20 total QCs and every counted quarter from 1951Q1 through the quarter before a qualifying 1952Q3–1955Q4 candidate quarter at or after onset, with at least six such quarters, under favorable all-period use or disregard (RS .132 B.2, C.2). For declared current establishment, that candidate must fit the immutable declared-end/continuity/death/FRA horizon. RS .480 A excludes the route when the lower-credit filling has 20/40 in the rule's disabled-quarter scan before October 1960; if only some fillings do, the alternate remains possible. Refuse automatically when this could change a failed disability predicate. Application conditions remain unmodeled. | | `DEEMED_FULLY_INSURED` | Wages and dates do not identify covered nonprofit employment or veteran status; retain the explicit flag (404.111–.112; RS .106/.107/.470). | | `TRANSITIONAL_INSURED` | Cohort dates alone do not identify the necessary historical benefit/application facts; retain the explicit flag (RS .101's transitional-benefit referrals). | | `RAILROAD_CREDITS`, `MILITARY_CREDITS` | Ordinary covered earnings do not identify railroad or military service and additional credits; retain explicit flags (RS .350; RS .120/.470). | @@ -683,8 +717,10 @@ already have automatic refusals in the QC conversion layer. Historical query/blindness/subsequent-special dates and uncaptured future increments also already trigger their refusals without a specialist flag. -A `CoverageCondition` explicitly triggers each specialist refusal. The -module does not infer excluded specialist facts from ordinary earnings. +A `CoverageCondition` explicitly triggers its specialist refusal after +all applicable establishment-impossibility checks. The module does not +infer excluded specialist facts from ordinary earnings or adjudicate a +flag's own conditions. Fiscal/short-year allocation helpers execute source arithmetic privately for conformance tests; they do not expand the public calendar-year API. @@ -751,21 +787,22 @@ to a statutory sentence that does not state it. | I6. An alien worker's actual pre2004 SSN assignment conflicts with declared SSPA applicability; birth on/after January 1, 2004 conflicts with declared exemption. Both never-assigned and an assigned SSN, or assignment before birth, remain invalid. A worker born before 2004 may pair a post2003 assignment or never-assigned status with an adjudicated exemption. | RS .102 B.1 says an alien assigned an SSN before 2004 "is exempt", including a nonwork SSN. B.3.b says, "If an alien worker could have legitimately been assigned an SSN before 1/1/2004, the worker is exempt from the requirements of section 211 of the SSPA." Its wrong-number SS-5 scenario issued another person's number "instead of assigning the alien worker their own SSN". Thus observed or convention-filled exemption overrides either later-assignment or never-assigned presumptions when legitimate pre2004 assignment was possible. Birth on/after January 1, 2004 rules out that exception independently of the assignment record. B.4.b's worker without an SSN "is nevertheless considered to meet the work SSN requirement" when work-authorized; meeting that requirement alone supplies no exemption. | | I7. Explicit quarterly QCs or positive quarterly wages cannot occur before birth, after the query/coverage-end quarter, or after the death quarter. Every required coverage year is declared exactly once through the earliest query, exit, or death year. | A213(a)(2)(B)(i), (v): "no quarter after the quarter in which an individual dies" and "no quarter shall be counted ... prior to the beginning of such quarter"; B404.146(a)-(b) agree. Birth and supplied-record exit caps, complete years, and no implicit zeros are interface premises. Annual counts are capped rather than dated after exit. Specialist earned-basis or additional-credit declarations remain refusals and do not reinterpret an explicit ordinary covered-quarter declaration. | | I8. A declared current establishment is invalid only after the shared possibility check excludes every route and every feasible prior/earnings filling. One ordinary filling must satisfy its insured start, recovery or administrative end, continuity, and overlap constraints together. | C320(b)(2) requires insured disability "in the calendar quarter in which you became disabled, or in a later calendar quarter"; C321(a) chooses the first such quarter. B404.130(a) supplies four ordinary rules and RS .480 supplies the alternate historical rule. The start horizon uses an inferred recovery month when I14 permits one, otherwise the declared end, together with continuity/query/death/FRA caps. Maximum credits establish only monotone insurance by that fixed horizon. A derived prior-quarter overlap requires a single lower-credit or enumerated filling whose first start also clears that overlap. An ordinary or alternate witness after the horizon cannot supply possibility. Foreign credits and the flag classes determine which credit-count proofs apply, in the refusal order above, before any alternate or boundary enumeration. The alternate's 20/40 exclusion instead uses U10's earliest date shared by every completion; a later witness cannot prove impossibility under every defensible reading of RS .480 A. | -| I9. Fewer than six maximum feasible ordinary lifetime QCs proves current establishment impossible only after foreign credits, credit-route flags, unresolved raw-earnings flags, and fully-route flags have preserved their possible routes. | B404.110(b)(1): "You need at least 6 QCs but not more than 40 QCs"; B404.130(a): "you must be fully insured". The flag table supplies each exception's captured premise. A record composed entirely of direct final QC declarations (`qc_count` or `qc_quarters`) and UNKNOWN years fixes or bounds all admissible final credits from RR compensation and fiscal/short taxable-year allocation. This is the direct-credit input contract, not a claim that ordinary RSDI credits exhaust freeze-only military credits: B404.133 expressly supplies the latter, so `MILITARY_CREDITS` remains a separate credit route even with direct rows. Any raw row leaves the raw-earnings route unresolved. Period exclusions alone cannot add ordinary QCs. RS .480 A separately requires 20 QCs, so `DISABILITY_BEFORE_1956` cannot rescue a below-six declaration. No ordinary floor applies to the unmodeled foreign-credit route (U11). | +| I9. Without a fully-route flag, fewer than six maximum feasible ordinary lifetime QCs proves current establishment impossible only after foreign credits, credit-route flags, and unresolved raw-earnings flags have preserved their possible routes. | B404.110(b)(1): "You need at least 6 QCs but not more than 40 QCs"; B404.130(a): "you must be fully insured". The flag table supplies each exception's captured premise. A record composed entirely of direct final QC declarations (`qc_count` or `qc_quarters`) and UNKNOWN years fixes or bounds all admissible final credits from RR compensation and fiscal/short taxable-year allocation. This is the direct-credit input contract, not a claim that ordinary RSDI credits exhaust freeze-only military credits: B404.133 expressly supplies the latter, so `MILITARY_CREDITS` remains a separate credit route even with direct rows. Any raw row leaves the raw-earnings route unresolved. Period exclusions alone cannot add ordinary QCs. RS .480 A separately requires 20 QCs and the explicit `DISABILITY_BEFORE_1956` flag adds no route beyond the automatic alternate, so it cannot rescue a below-six declaration. Fully-route flags bypass this fully insured floor but still obey I15 and I16 where applicable. No ordinary floor applies to the unmodeled foreign-credit route (U11). | | I10. The supported calendar, mandatory historical sex, and explicit establishment declaration must be supplied: birth years 1870–9900, query years through 9990, sex for births before January 2, 1913, and establishment provenance whenever onset is present. | These are interface-domain requirements. B404.110(b)(2) and .132 apply different historical male/female endpoints; B404.110(c) excludes only a period "we established for you". Missing facts are not inferred. Calendar limits reserve space for date arithmetic and assert no legal incapacity outside the implementation domain; alternative credit routes cannot supply missing declared facts. | | I11. A continues-through observation requires established disability, cannot precede medical onset or the first feasible insured start, cannot exceed the pre-FRA or death boundary, and cannot follow a declared administrative end. | C320(b)(2) and C321(a) require the insured start; A216(i)(2)(D) and C321(c) bound the period's end. A declaration that a period was in force on a date requires that date to lie within one possible period. This is a dated observation, not an asserted ending; a date later than the query is allowed. Provenance and convention identifiers follow the existing fact schema. | | I12. A raw-credit conversion refusal cannot hide established-period impossibility that every feasible filling of that row preserves. | C320(b)(2), C321(a), and B404.110(b)(1) supply the insured-start and six-QC premises. The #530 input contract puts input errors before coverage refusals. Schema validation remains first; the four conversion refusals are deferred only for this proof, with unresolved rows bounded by feasible ordinary quarters. A surviving filling preserves the original refusal reason and note rather than manufacturing a supported status. | | I13. If no starting quarter from onset through the immutable horizon clears all supplied prior-period quarters, current establishment is impossible independently of credit fillings, their count, or a specialist route. | C320(b)(2) and C321(a) require an insured beginning within that interval; I4's nonoverlapping-quarter representation applies to that same beginning. A credit route cannot move a candidate outside the fixed interval or remove a supplied prior quarter. This fixed contradiction is checked before specialist possibility and filling enumeration; it does not treat UNKNOWN prior history as supplied empty history. | | I14. A declared recovery-only historical end implies a recovery month two months earlier; recovery before the onset month or a derived start after that month is invalid. | C321(b) ends the period on "the last day of the second month following the month in which your disability ended". C320(b)(2) and B404.131(a) require an insured quarter in which the worker was disabled, so an administrative grace month cannot supply a new disabled quarter. The helper returns no recovery inference for an end on/after February 1, 1981, in/after the month preceding FRA, or in/after the death month. These carve-outs preserve the existing validity horizon and make no claim about paragraph (c) recovery or administrative ending rules. | -| I15. With known prior history, no blindness, no foreign credits, no credit-route flag, and no raw-earnings flag outside a complete direct-QC envelope, fewer maximum feasible lifetime QCs than the lowest remaining recent-rule requirement proves establishment impossible before fully-route refusals or coverage enumeration. | B404.130(a) requires a recent rule "and you must be fully insured". The flag table's fully-route rules cannot change the independent recent-credit requirement. B404.130(b) needs 20 QCs; (c)–(d) permit the special half-elapsed-quarter rule with six-QC floor and 20-QC ceiling; RS .480 A also needs 20. At the earliest candidate start, remove every prior-period quarter from special elapsed time, including credited endpoints. Every actual use/disregard witness has at least those elapsed quarters, and later starts cannot reduce them. Taking the smallest applicable requirement therefore cannot exceed any true route minimum. Ignoring the fully insured prerequisite and window availability only relaxes the bound. Blindness (B404.130(e)) needs only fully insured status, and UNKNOWN prior history could remove further quarters; both disable the stronger proof. | +| I15. With known prior history, no blindness, no foreign credits, no credit-route flag, and no raw-earnings flag outside a complete direct-QC envelope, fewer maximum feasible lifetime QCs than the lowest remaining recent-rule requirement proves establishment impossible before fully-route refusals or coverage enumeration. | B404.130(a) requires a recent rule "and you must be fully insured". The flag table's fully-route rules cannot change the independent recent-credit requirement. B404.130(b) needs 20 QCs; (c)–(d) permit the special half-elapsed-quarter rule with six-QC floor and 20-QC ceiling; RS .480 A also needs 20. At the earliest candidate start, remove every prior-period quarter from special elapsed time, including credited endpoints. Every actual use/disregard witness has at least those elapsed quarters, and later starts cannot reduce them. Taking the smallest applicable requirement therefore cannot exceed any true route minimum. Ignoring the fully insured prerequisite and window availability only relaxes the bound. Blindness (B404.130(e)) needs only fully insured status, and UNKNOWN prior history could remove further quarters; both disable this numerical proof and I16's recent scan. The minimum remains ahead of every boundary enumeration, including the recent scan. | +| I16. With known prior history, no blindness, and no route adding credits outside the declared envelope, a fully-route flag cannot establish a current period unless some nonoverlapping candidate quarter meets a recent rule under maximum feasible credits or the automatic pre1956 alternate remains possible. | B404.130(a) requires one rule "and you must be fully insured"; (b) requires 20 QCs in 40 quarters; (c) and (d) supply the under31 and subsequent-special recent alternatives. C320(b)(2) permits the onset quarter or a later disabled quarter, and C321(a) selects the first qualifying quarter. The scan includes the onset and horizon quarters and skips every candidate within a supplied prior-period quarter using I13's same overlap predicate. It retains B404.130(f)'s favorable all-period use or disregard and annual assignment, and relaxes only the fully insured prerequisite. Upper credits bound every feasible filling; failure there therefore proves every lower filling lacks a recent witness. An open RS .480 route remains an independent possibility for a fully-route flag. A complexity refusal is not impossibility and preserves the flag's own named refusal. The scan tests no flag-specific condition. | | ID and UNKNOWN collapse | Captured text and alternative-route defense | | --- | --- | | U1. UNKNOWN prior history can collapse to empty solely for impossibility validation when no earliest prior period could start insured, on/after birth, before current onset and the FRA end. | C320(b)(2) and C321(a) require an insured beginning without a still-earlier period. A216(i)(2)(A) permits "five full calendar months' duration or" DIB entitlement "for one or more months". The scan therefore admits a one-month period and maximum feasible earnings. Any possible ordinary or specialist starting route stops the proof. It establishes no observed empty-history fact. | | U2. UNKNOWN current establishment needs no new-period alternative if there is no medical onset or onset is at/after the statutory latest starting month. | A216(i)(2)(A)-(D) and C321 prohibit a period without disability or a nonempty pre-FRA interval. This removes an impossible new-period alternative only; it does not remove UNKNOWN prior history or an existing period's UNKNOWN administrative end. | | U3. With unknown prior/current periods, true ordinary FULLY and CURRENTLY status under favorable all-period disregard decides true. A DISABILITY witness must also survive any current-establishment completion that ends the disability before that witness. | C320(a): "If benefits ... would be denied or reduced because of a period of disability, the period of disability will not be taken into consideration." B404.130(f) also permits counting all prior quarters if favorable. RS .120 requires all periods used or all disregarded; selective exclusions are not assumed. Specialist credit regimes are refused first. | -| U4. With unknown periods, fewer than six maximum feasible QCs decides false only on the ordinary route after specialist possibilities are excluded; it supplies no foreign-credit impossibility proof. | B404.110(b)(1) and B404.130(a) supply the ordinary six-QC prerequisite. U3's disregard cannot manufacture credits. UNKNOWN prior history disables I15. Foreign credits, fully-route and credit-route flags, and raw-earnings flags outside a complete direct envelope preserve named refusals. The direct-envelope contract and the declared pre1956 alternate still obey I9; blindness alone supplies no credits and does not replace the ordinary fully insured prerequisite. | +| U4. With unknown periods, fewer than six maximum feasible QCs decides false only on the ordinary route after specialist possibilities are excluded; it supplies no foreign-credit impossibility proof. | B404.110(b)(1) and B404.130(a) supply the ordinary six-QC prerequisite. U3's disregard cannot manufacture credits. UNKNOWN prior history disables both I15 and I16 and preserves a fully-route flag's named refusal even when every known recent window is empty. Foreign credits, credit-route flags, and raw-earnings flags outside a complete direct envelope also preserve named refusals. Without a fully-route flag, the direct-envelope contract and declared pre1956 alternate still obey I9; that alternate flag adds no route beyond B4. Blindness alone supplies no credits and does not replace the ordinary fully insured prerequisite. | | U5. UNKNOWN earnings decide a requested Boolean only if all lower/upper ordinary earnings witnesses agree, under the permitted fixed-period/all-period treatments; an uncertain established start refuses only after at least one feasible filling survives. | B404.143 credits one QC for each increment, maximum four; B404.130 and .146 supply assignment/exclusion rules. Adding ordinary QCs cannot invalidate a fixed treatment. A derived start cannot be silently held fixed when the completion changes it. If a lower or upper representative cannot construct the declared period, but another single filling meets its end, continuity, and prior-overlap constraints, the public result is `unknown_earnings_years_decide_status`. If no ordinary filling can qualify by the declared end and all independent routes are impossible, it is an input error and creates no row. A deferred raw-conversion row uses temporary unknown fillings only for possibility, then retains its conversion refusal. Specialist possibilities and administrative-end candidates are considered separately. | | U6. UNKNOWN administrative end decides a status only when every end-quarter candidate from start through query/cap, plus permitted continuation, agrees, after applying any continuity lower bound. | A216(i)(2)(D) uses "whichever ... is the earlier"; C321(c)(3) includes "the last month for which you received benefits" after substantial gainful activity. Medical continuity cannot exclude early ends; a dated administrative continuity observation can. FRA/death caps limit the latest candidate and do not turn the unknown into a fact. Both ending and prior-history unknown facts remain disclosed when both are missing; UNKNOWN prior history uses the universal envelopes rather than inventing a derived current period to enumerate. The unchanged completion enumeration can include early endings rejected by I14 if declared concretely. Agreement across that larger set still implies agreement across every valid completion, while disagreement can preserve an extra refusal. An actual supplied end keeps its declared-date semantics; known ending provenance requires an ending date. | | U7. UNKNOWN SSPA applicability preserves an ordinary QC-only false status, but never a QC-only true status. | RS .102 B.2 says the worker "must meet one of the following additional requirements" and may fail "even if" the QC requirement is met. Applicability can remove ordinary insurance and cannot supply missing QCs. Known applicability retains adjudication refusal; any separate specialist path is refused first. | @@ -780,7 +817,7 @@ to a statutory sentence that does not state it. | B1. UNKNOWN annual ordinary QCs range from zero through four, reduced by assignable birth/query/death/exit quarters. Deferred raw-conversion rows use their feasible minimum/maximum fillings only for establishment possibility. Exact annual amounts are monotone in earnings; every calendar year stays in 0–4. | B404.143: "we cannot credit you with more than four QCs for any calendar year"; A213(a)(2)(B)(vi) prohibits duplicate calendar-quarter QCs; B404.146 excludes unbegun/death quarters. Birth/exit are supplied-record premises. Additional-credit regimes retain refusal and cannot escape this bound through an ordinary result. Deferred rows still raise their original conversion refusal after a valid possibility survives; no temporary filling is exposed as a computed status. | | B2. Ordinary fully insured requirements lie in 6–40 and exclude only established disability years. Every elapsed-year endpoint uses its relevant candidate year and the historical sex/cohort rule. | B404.110(b)(1), (b)(2), (c), .132; A214(a) says "not counting ... any year any part of which was included in a period of disability". Medical onset without establishment cannot freeze years. Deemed/transitional alternatives are refused before using the ordinary requirement as universal. | | B3. A simplified-pre1951 possibility uses the smallest known freeze requirement, or six for unresolved establishment/history, and maximum post1950 ordinary credits without exclusions. UNKNOWN pre1951 raw wages remain potentially decisive. | A213(c) grants "one quarter of coverage for each $400" subject to resulting fully insured status; B404.110(c)-(d); RS .315 B.1-B.2 record alternate historical/application conditions. This is an over-approximation for refusal, not a computed deemed-credit answer. A favorable ordinary witness with a higher requirement cannot narrow it. | -| B4. An alternate-pre1956 possibility uses maximum feasible QCs and an eligible 1952Q3–1955Q4 start with at least 20 total QCs and at least six continuous credited clock quarters, under favorable all-period use or disregard. It survives unless lower credits establish 20/40 in U10's shared disabled-quarter scan. | RS .480 A requires "at least 20 quarters of coverage" and "all quarters beginning with 03/51 ... are QCs", with "at least six"; B.1 permits the first freeze day 07/01/52 through 12/31/55. RS .132 B.2 applies prior-period exclusions to the continuous alternate clock, retaining credited beginning/ending quarters; C.2 requires all periods used or all disregarded. Candidate starts obey I8/I14's latest permissible horizon, so recovery before July 1952 cannot be rescued by the first alternate start. Exclusion instead obeys U10's earliest shared date, including the two-month offset for declared ends and continuity. A lower-credit ordinary 20/40 witness in that shared interval removes the route for all credit fillings; an upper-only or later witness preserves the named refusal. Unmodeled application conditions can remove candidates but do not prove an input error. Explicit specialist flags remain independent. | +| B4. An alternate-pre1956 possibility uses maximum feasible QCs and an eligible 1952Q3–1955Q4 start with at least 20 total QCs and at least six continuous credited clock quarters, under favorable all-period use or disregard. It survives unless lower credits establish 20/40 in U10's shared disabled-quarter scan. | RS .480 A requires "at least 20 quarters of coverage" and "all quarters beginning with 03/51 ... are QCs", with "at least six"; B.1 permits the first freeze day 07/01/52 through 12/31/55. RS .132 B.2 applies prior-period exclusions to the continuous alternate clock, retaining credited beginning/ending quarters; C.2 requires all periods used or all disregarded. Candidate starts obey I8/I14's latest permissible horizon, so recovery before July 1952 cannot be rescued by the first alternate start. Exclusion instead obeys U10's earliest shared date, including the two-month offset for declared ends and continuity. A lower-credit ordinary 20/40 witness in that shared interval removes the route for all credit fillings; an upper-only or later witness preserves the named refusal. Unmodeled application conditions can remove candidates but do not prove an input error. An explicit `DISABILITY_BEFORE_1956` flag adds no route beyond this check. A fully-route flag may rely on this same alternate possibility when its ordinary recent rules fail; neither flag adjudicates the alternate's application conditions. | | B5. Universal recent, fully-prerequisite, and annual count envelopes use zero through maximum feasible ordinary lifetime/year QCs whenever unknown periods/earnings can switch witnesses. | A213(a)(2)(B)(vi) prohibits double credit; B404.146(d) excludes interiors unless disregarded. Every concrete ordinary assignment is a subset of feasible unique lifetime quarters. The envelope permits every witness, even when adding QCs switches to a lower-count witness. Specialist possibilities remain refusals. | | B6. With known earnings and an UNKNOWN ending, returned count bounds include all end-candidate counts admitted by continuity; with entirely known facts they remain exact. | B404.120(b), .130(f), .146(d) distinguish credited endpoints and excluded interiors. All candidate quarters are enumerated, including early endpoints and capped-FRA candidates, subject to any continues-through observation; extrema therefore cover each completion. A continuity date is never inserted as a credited endpoint. No monotonic endpoint-count premise is used. | | B7. DLI lies through query without frozen exit, or through the pre-FRA-quarter/death horizon with frozen coverage; `None` is the bottom bound. A future exit cannot remove query censoring. | RS .148 defines DLI as "the last day in the last quarter" in which status is met and limits the search relative to FRA. B404.146(b) caps credits after death; A216(i)(2)(B) caps new periods. Future undeclared work is not assumed zero. Specialist routes are refused before this ordinary DLI calculation. | @@ -788,7 +825,7 @@ to a statutory sentence that does not state it. | B9. With unknown periods the disregard DLI is a lower bound and the permitted query/FRA/death horizon is the upper bound; unknown SSPA applicability reduces any positive DLI lower bound to `None`. | C320(a) permits favorable disregard; B404.130(f) permits counting all prior-period quarters; RS .102 B.2 imposes an additional requirement. The bound does not infer a particular recovery or history. Exemption can recover the ordinary upper witness but cannot exceed the calendar horizon. | | B10. UNKNOWN-ending DLI bounds include every end candidate. With an unresolved ongoing end, known prior history, and frozen-exit future horizon beyond query, the named DLI-horizon refusal remains. | C321(c)'s alternative endings and RS .148's last qualifying quarter permit different historical DLI witnesses. The candidate extrema bound all declared endings; no recovery beyond the query is inferred. Refusal covers the unobserved future administrative fact. | | B11. At most 4,096 combinations of disability endpoint assignments are searched exactly, after any applicable impossibility proof. | B404.143(b) and RS .230 permit favorable assignment; B404.130(f) makes credited endpoints decisive. Fixed-overlap, six-QC, and I15's minimum-requirement checks precede `_boundary_variants`, including both alternate-path calls and UNKNOWN-prior-history feasibility. A remaining excess returns `disability_boundary_assignments_unsupported`; computational complexity is neither a statutory impossibility bound nor permission to retain an all-invalid declaration. | -| B12. Ordinary counted windows have 13 quarters for current insurance and 40 for ordinary disability; young/subsequent special windows require half their elapsed quarters after dropping an odd remainder, with a six-QC minimum and 20/40 ceiling. | B404.120(a) says "13-quarter period"; .130(b) says "20 QCs in the 40-quarter period"; .130(c)-(d) and A216(i)(3)(B) supply the half-quarter, odd-remainder, and 6/12 alternatives. Blindness uses only the fully insured prerequisite, and pre1956/flagged specialist paths retain refusal rather than being forced through an ordinary window. | +| B12. Ordinary counted windows have 13 quarters for current insurance and 40 for ordinary disability; young/subsequent special windows require half their elapsed quarters after dropping an odd remainder, with a six-QC minimum and 20/40 ceiling. | B404.120(a) says "13-quarter period"; .130(b) says "20 QCs in the 40-quarter period"; .130(c)-(d) and A216(i)(3)(B) supply the half-quarter, odd-remainder, and 6/12 alternatives. Blindness uses only the fully insured prerequisite. A fully-route flag must still leave a recent-rule witness or possible automatic pre1956 alternate where I16 applies; the pre1956 flag adds no route beyond that alternate. Specialist paths retaining possibility receive their named refusal. | | B13. Indexed annual QC amounts are at least the prior year's statutory increment and the rounded indexed 1978 amount, with nearest-$10 rounding and $5 ties upward. | A213(d)(2) chooses "the larger of" the prior increment and indexed amount, rounded to "the next higher multiple of $10" at a $5 tie. This exact parameter calculation has no disability or specialist alternative; input-domain checks require positive NAWI and a statutory prior increment. | | B14. Declaring continuity never widens the administrative-end candidate set; every returned status and count envelope remains valid for every retained concrete ending. | C321(c)'s ending events still govern. Set intersection with ends on/after the observation can only remove candidates; it creates neither an ending nor a new credit. The universal envelope remains unchanged where other unknown facts require it. | | B15. Ordinary establishment overlap resolution enumerates at most 4,096 unknown-credit fillings after its fixed-date monotonicity, candidate-quarter, six-QC, and minimum-requirement proofs. | C320(b)(2) and C321(a) require one insured beginning consistent with the complete declaration. I13 settles fixed-quarter overlap and I15 settles a known-history nonblind lifetime-QC shortfall before enumeration. If neither settles the declaration, a search beyond the limit returns `disability_boundary_assignments_unsupported`; it asserts neither a concrete filling nor an input error. | @@ -826,10 +863,10 @@ The specialist test is split by flag class: `test_exact_classification_keeps_raw_earnings_flagged_routes`, `test_exact_classification_keeps_independent_credit_routes`, and `test_exact_classification_bounds_flags_that_add_no_declared_credit`. -Each rules out an automatic pre1956 witness to test the explicit routes -independently. Fully-route flags -are paired at a proved recent-credit shortfall and the exact minimum; -raw-earnings flags are paired with a complete direct envelope and an +Each rules out an automatic pre1956 witness to isolate the flag classes. +Fully-route flags are paired at a proved recent-credit shortfall and the +exact minimum. Raw-earnings flags are paired with a complete direct +envelope and an unresolved raw row. Credit-route flags retain refusals with a complete direct envelope, while the declared pre1956 route cannot bypass a below-six shortfall. Blindness and UNKNOWN prior history preserve the @@ -1042,29 +1079,40 @@ denominators: | Invariant | Executing tests | | --- | --- | | Adding foreign credits to a declaration clearing fixed chronology always preserves the totalization refusal, one row, and exact weight, independently of its own-QC count or flags. Fixed overlap still produces an input error and no row. | `test_foreign_credit_refusal_is_independent_of_own_qc_count` (Hypothesis); `test_foreign_credits_refuse_without_an_own_qc_floor`; `test_fixed_overlap_precedes_every_flag_and_foreign_route` | -| With known prior history and no blindness, any flag set supplying no additional credit under the complete direct-envelope contract leaves a total-QC shortfall below the recent-rule minimum input-invalid. The expected minimum is computed independently of `_minimum_current_period_qcs`; this numerical proof does not decide every temporal shortfall described below. | `test_no_credit_flag_set_cannot_hide_independently_proved_shortfall` (Hypothesis); `test_no_credit_flag_shortfall_and_exact_minimum_pair`; `test_review_recent_credit_shortfall_cannot_be_cured_by_deeming` | +| With known prior history and no blindness, any flag set supplying no additional credit under the complete direct-envelope contract leaves a total-QC shortfall below the recent-rule minimum input-invalid. The expected minimum is computed independently of `_minimum_current_period_qcs`; round 12 supplements this numerical proof with the candidate-quarter scan below. | `test_no_credit_flag_set_cannot_hide_independently_proved_shortfall` (Hypothesis); `test_no_credit_flag_shortfall_and_exact_minimum_pair`; `test_review_recent_credit_shortfall_cannot_be_cured_by_deeming` | | A flag cannot turn a declaration meeting every ordinary requirement into an input error. At the exact ordinary or under31 minimum, each flag retains its own reason, one row, and exact weight. | `test_no_flag_rejects_declaration_meeting_every_requirement` (Hypothesis); `test_no_credit_flag_shortfall_and_exact_minimum_pair`; `test_credit_route_keeps_refusal_even_with_complete_direct_envelope` | | Fully-route flags retain their named refusals with blindness below six actual QCs or UNKNOWN prior history. The declared pre1956 alternate cannot bypass the ordinary six-QC floor even with blindness, but at 20 QCs retains its refusal. | `test_fully_route_refuses_when_recent_credit_proof_does_not_apply`; `test_pre1956_flag_with_blindness_keeps_ordinary_six_qc_floor` | | A complete direct envelope bounds every raw-earnings flag, including UNKNOWN rows; a raw row preserves its unmodeled allocation route. Military and Medicare government credits preserve a separate route even with direct rows. Combining flags preserves each independent route. | `test_raw_earnings_flag_preserves_route_only_without_direct_envelope`; `test_exact_classification_bounds_flags_that_add_no_declared_credit`; `test_credit_route_keeps_refusal_even_with_complete_direct_envelope`; `test_two_flag_classes_preserve_each_independent_route` | -Round 11 has a remaining temporal limit. Its numerical recent-credit proof -does not test whether sufficient total credits fall inside any candidate -window before a fully-route flag returns possible. An invented worker born +Round 12 closes round 11's temporal limitation. An invented worker born February 2, 1960, with onset January 15, 2000, an established period ending December 31, 2000, known empty prior history, no blindness, and 20 direct -QCs entirely in 1978–1982 has zero QCs in every 2000 candidate 40-quarter -window. Without a flag the declaration is invalid. Each fully-route flag -instead retains its named refusal, one row, and weight 13/7 under the -prescribed order. Reducing the total to 19 makes every such flagged -declaration invalid under the numerical proof. Section 404.130(b)(2) -requires 20 QCs in the 40-quarter period, independently of fully insured -status under paragraph (a); the fully-route premises above supply no -recent-window credits. This residual is conservative over-refusal rather -than evidence of a concrete valid completion. The scratch regression -`test_fully_only_flag_cannot_supply_missing_recent_window_qcs` records the -four failing cases. The requested numerical-proof correction leaves the -later temporal scan unchanged; this additional ordering issue remains -unfixed. +QCs entirely in 1978–1982 has zero QCs in every candidate 40-quarter +window. The unflagged declaration and each fully-route declaration now +raise `InvalidFamilyInput`, with no evaluator row. Reducing the total to +19 remains invalid under the earlier numerical proof. The new recent scan +keeps both inclusive quarter edges, the immutable horizon and recovery +bound, prior-period overlap, favorable assignment, all-period use or +disregard, and under31/subsequent-special alternatives. It ignores only +the fully insured prerequisite. A recent witness preserves the flag's +named refusal even when the ordinary fully insured requirement fails. +Blindness, UNKNOWN prior history, an open automatic pre1956 alternate, or +an unresolved scan complexity likewise preserves possibility. The +`DISABILITY_BEFORE_1956` flag has no separate early return: an onset after +1955 with neither an ordinary nor an alternate route is invalid, while +either possible route preserves the flag's named refusal. These are +establishment-classification corrections under 404.130(a)–(d), C320(b)(2), +C321(a), and RS .480 A–B.1, not adjudications of the flags' own conditions. + +| Invariant | Executing tests | +| --- | --- | +| With known prior history, no blindness, and only flags adding no credits, a declaration with onset after 1955 is input-invalid when an independent plain-arithmetic assignment/window oracle finds no recent witness. The generated grid includes declarations before age 31. Every invalid declaration has no evaluator row or weight. | `test_independent_recent_oracle_proves_no_credit_flag_impossibility` (Hypothesis); `test_old_lifetime_credits_cannot_supply_any_recent_window` | +| A fully-route flag relaxes only the fully insured prerequisite. With the alternate absent, its establishment classification matches the independent recent oracle in both directions; a recent witness retains its named refusal even when the ordinary fully insured prerequisite fails. A possible alternate independently preserves that refusal. | `test_fully_flag_changes_fully_only_against_unflagged_recent_oracle` (Hypothesis); `test_fully_flag_exactness_includes_independent_alternate_oracle` (Hypothesis); `test_fully_route_relaxes_only_fully_insured_when_recent_rule_passes`; `test_fully_route_keeps_alternate_when_ordinary_recent_rule_is_closed` | +| At every tested quarter, a true ordinary DISABILITY witness stays true when only the fully insured prerequisite is relaxed on identical credits. | `test_witness_keyword_only_relaxes_fully_prerequisite` (Hypothesis) | +| The recent scan includes both the onset quarter and horizon quarter, and the horizon quarter counts even when the end falls inside it. It does not admit a witness beyond an inferred recovery bound. A credit one quarter too old cannot enter any candidate window. | `test_scan_includes_onset_and_the_earliest_quarter_of_forty`; `test_scan_includes_horizon_quarter_and_stops_at_recovery_bound`; `test_scan_reaches_last_candidate_quarter_even_with_end_inside_quarter` | +| The recent scan retains under-31 and subsequent-special requirements, favorable use of every prior period or disregard of every period, credited endpoints, and the shared rejection of candidate quarters inside supplied prior periods. | `test_special_recent_requirement_and_one_short`; `test_subsequent_special_recent_rule_can_pass_below_twenty_qcs`; `test_recent_window_uses_all_prior_periods_or_disregards_all`; `test_candidate_inside_prior_period_does_not_supply_recent_witness` | +| Blindness and UNKNOWN prior history preserve fully-route refusals even with empty recent windows. UNKNOWN recent years preserve possibility whenever an admissible filling supplies a recent witness, and every surviving concrete filling retains the flag's refusal. Complexity preserves that flag reason rather than substituting a computational refusal. | `test_empty_windows_keep_fully_route_blindness_and_unknown_prior_bypasses`; `test_unknown_recent_years_and_every_surviving_filling_keep_flag_reason`; `test_complexity_preserves_fully_route_reason` | +| A declared pre1956 flag adds no establishment route beyond the automatic alternate: onset after 1955 with no ordinary route is invalid; either an ordinary witness or the historical alternate retains the named refusal. Credit-route and unbounded raw-earnings flags remain capable of adding credits, and a deferred conversion keeps its original reason when a recent witness remains possible. Surviving outcomes retain one evaluator row and exact weight 11/5. | `test_pre1956_flag_cannot_open_a_route_after_1955`; `test_pre1956_flag_keeps_named_refusal_when_alternate_conditions_hold`; `test_pre1956_flag_keeps_named_refusal_when_ordinary_route_is_open`; `test_credit_and_unbounded_raw_earnings_flags_can_add_recent_credits`; `test_deferred_conversion_keeps_original_refusal_with_possible_recent_rule` | The round-8 UNKNOWN-ending and round-9 UNKNOWN-establishment completion properties above remain in force with the corrected shared disabled month. @@ -1254,9 +1302,10 @@ permitted July 1, 1952 start. The declaration is therefore input-invalid. A July declared end now also fails, because it implies May recovery. A September declared end implies July recovery and preserves the automatic route. July and September continuity observations instead retain the -unknown-ending route and its named refusal. This source-required chronological check is -independent of the ordinary possibility scan and of explicit specialist -flags. A woman born July 2, 1887 reaches FRA in July 1952, so her +unknown-ending route and its named refusal. This source-required +chronological check applies to the automatic alternate even with an +explicit `DISABILITY_BEFORE_1956` declaration or a fully-route flag. A +woman born July 2, 1887 reaches FRA in July 1952, so her period's latest end is June 30 and the alternate July 1 start is already too late. An August 2 birth instead permits that start. This actual month-before-FRA limit is shared by the ordinary and automatic scans. @@ -1552,8 +1601,15 @@ established period, even with `DEEMED_FULLY_INSURED`. The corrected result is an input error and zero rows; 20 recent QCs preserve the deemed-full refusal, one row, and weight 11/5. The fully-route, recent-test, raw-earnings, and credit-route classifications above follow the captured -premises and introduce no additional discretionary reading. Neither -finding adjudicates payment, so it establishes no dollar change. +premises and introduce no additional discretionary reading. Round 12 +also applies the recent rule to the temporal location of those credits: +20 old lifetime QCs cannot cure an empty candidate window. RS .480 B.1's +"the last day on which it can begin is 12/31/55" also bars a separate +pre1956-flag escape for a later onset. The flag adds no route beyond the +automatic alternate check. Neither correction tests a flag's own +conditions; an explicitly declared fully insured route remains a supplied +fact even if its cohort would not satisfy 404.112. These corrections make +no payment adjudication and establish no dollar change. Mutation checks are recorded in [`track_b_insured_status_mutations.json`](track_b_insured_status_mutations.json). diff --git a/docs/design/track_b_insured_status_mutations.json b/docs/design/track_b_insured_status_mutations.json index faa9654b6..b6bdd25cd 100644 --- a/docs/design/track_b_insured_status_mutations.json +++ b/docs/design/track_b_insured_status_mutations.json @@ -3488,5 +3488,357 @@ } ], "round_11_note": "Eleven deliberate isolated in-memory mutations were caught and discarded. All three new properties bite. Every run audited zero restricted opens or spawned processes and verified original implementation bytes unchanged. The exact commands and standalone reproductions above pin the final formatted source. No committed mutation remains.", - "round_11_final_source_sha256": "aebd9223724bc6694e320590a72cd744cb7309dbcb92600bd7ffb11f5d4ca4d1" + "round_11_final_source_sha256": "aebd9223724bc6694e320590a72cd744cb7309dbcb92600bd7ffb11f5d4ca4d1", + "round_12_mutations": [ + { + "name": "keyword_noop", + "source_sha256": "8ef822d784136ae3b821cb75ec270e945d1972d5cfa10f4ae533fd65f6c0f018", + "mutated_source_sha256": "8b2793b9cd445eafcd04f938d3fee6114ed779a12f40e269d77e827dfce38282", + "changes": [ + { + "before": "(fully or ignore_fully_insured)", + "after": "fully" + } + ], + "pytest_arguments": [ + "-q", + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "--tb=short", + "tests/test_track_b_insured_status_fix_round_12.py::test_witness_keyword_only_relaxes_fully_prerequisite" + ], + "command": "env OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONDONTWRITEBYTECODE=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round12 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round12 PYTHONPATH=\"$PWD/src:$PWD\" TRACKB_ROUND12_MUTATION=/Users/maxghenis/.subfleet/worktrees/20261031-164238-trackb-fix-insured-12/scratch/review/round-12-mutation-keyword_noop.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_12_named.py -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_12.py::test_witness_keyword_only_relaxes_fully_prerequisite > scratch/review/round-12-mutation-keyword_noop.txt 2>&1", + "result": "1 failed in 3.82s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_12.py::test_witness_keyword_only_relaxes_fully_prerequisite" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "mechanism": "Compile modified module in memory only; source bytes verified unchanged after execution", + "restored": true, + "reproduction_command": "env OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONDONTWRITEBYTECODE=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round12 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round12 PYTHONPATH=\"$PWD/src:$PWD\" /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_12.py::test_witness_keyword_only_relaxes_fully_prerequisite <<'PY'\n\"\"\"Run named invented-data tests with restricted-file open auditing.\"\"\"\n\nimport hashlib\nimport json\nimport os\nimport sys\nfrom pathlib import Path\n\nROOT = Path(__file__).resolve().parents[2]\nBARRED_NAMES = {\n \"gates.yaml\",\n \"adjusted_poverty.py\",\n \"rows.py\",\n \"ssa_trust_fund_interest_rates_2026.json\",\n \"urban2010_fra68_comparison.md\",\n \"boomers2004_uniform_cut_comparison.md\",\n \"minimum_benefits_comparison.md\",\n \"m6_projection_engine.md\",\n \"mint8_table_user_guide.source.html\",\n \"test_anchor_provenance_erratum.py\",\n}\nCOUNTS = {\"restricted_opens\": 0, \"subprocess.Popen\": 0, \"os.system\": 0}\n\n\ndef audit(event, arguments):\n if event == \"open\" and isinstance(arguments[0], (str, bytes)):\n path = os.fsdecode(arguments[0])\n name = Path(path).name\n if (\n name in BARRED_NAMES\n or name.startswith((\"adjusted_poverty.\", \"rows.\"))\n or \"/PolicyEngine/psid-data/\" in path\n or \"/microcosm-launch-evidence/\" in path\n or \"/dynasim-refs/\" in path\n or \"/claude-501/\" in path\n ):\n COUNTS[\"restricted_opens\"] += 1\n raise RuntimeError(path)\n elif event in (\"subprocess.Popen\", \"os.system\"):\n COUNTS[event] += 1\n\n\ndef main():\n for name in (\n \"POPULACE_DYNAMICS_PSID_DIR\",\n \"POPULACE_DYNAMICS_EPUF_DIR\",\n ):\n assert os.environ[name] == \"/nonexistent/trackb-round12\"\n assert sys.argv[1:]\n assert all(\n not argument.startswith(\"tests/\") or \".py\" in argument\n for argument in sys.argv[1:]\n )\n sys.addaudithook(audit)\n from populace_dynamics.track_b import insured_status as insured\n\n source_path = Path(insured.__file__)\n original = source_path.read_bytes()\n baseline_path = os.environ.get(\"TRACKB_ROUND12_SOURCE\")\n if baseline_path:\n baseline = Path(baseline_path).read_bytes()\n exec(compile(baseline, str(source_path), \"exec\"), insured.__dict__)\n print(\"BASELINE\", hashlib.sha256(baseline).hexdigest(), flush=True)\n spec_path = True\n if spec_path:\n spec = {'name': 'keyword_noop', 'source_sha256': '8ef822d784136ae3b821cb75ec270e945d1972d5cfa10f4ae533fd65f6c0f018', 'changes': [{'before': '(fully or ignore_fully_insured)', 'after': 'fully'}]}\n assert hashlib.sha256(original).hexdigest() == spec[\"source_sha256\"]\n source = original.decode()\n for change in spec[\"changes\"]:\n assert source.count(change[\"before\"]) == 1, change[\"before\"]\n source = source.replace(change[\"before\"], change[\"after\"], 1)\n exec(compile(source, str(source_path), \"exec\"), insured.__dict__)\n print(\n \"MUTATION\",\n spec[\"name\"],\n \"source_sha256=\" + hashlib.sha256(original).hexdigest(),\n \"mutated_sha256=\" + hashlib.sha256(source.encode()).hexdigest(),\n flush=True,\n )\n import pytest\n\n try:\n result = pytest.main(sys.argv[1:])\n finally:\n assert source_path.read_bytes() == original\n print(\"OPEN_AUDIT\", json.dumps(COUNTS, sort_keys=True), flush=True)\n return result\n\n\nif __name__ == \"__main__\":\n raise SystemExit(main())\nPY" + }, + { + "name": "fully_route_without_recent_scan", + "source_sha256": "8ef822d784136ae3b821cb75ec270e945d1972d5cfa10f4ae533fd65f6c0f018", + "mutated_source_sha256": "fe97f55de6c11124b0c566472b8164ae407f2b9d8697a5a3003b9abd50b06410", + "changes": [ + { + "before": " if fully_route and _recent_rule_possible(\n person, credits, horizon, exit_month\n ):\n", + "after": " if fully_route:\n" + } + ], + "pytest_arguments": [ + "-q", + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "--tb=short", + "tests/test_track_b_insured_status_fix_round_12.py::test_independent_recent_oracle_proves_no_credit_flag_impossibility", + "tests/test_track_b_insured_status_fix_round_12.py::test_fully_flag_changes_fully_only_against_unflagged_recent_oracle" + ], + "command": "env OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONDONTWRITEBYTECODE=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round12 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round12 PYTHONPATH=\"$PWD/src:$PWD\" TRACKB_ROUND12_MUTATION=/Users/maxghenis/.subfleet/worktrees/20261031-164238-trackb-fix-insured-12/scratch/review/round-12-mutation-fully_route_without_recent_scan.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_12_named.py -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_12.py::test_independent_recent_oracle_proves_no_credit_flag_impossibility tests/test_track_b_insured_status_fix_round_12.py::test_fully_flag_changes_fully_only_against_unflagged_recent_oracle > scratch/review/round-12-mutation-fully_route_without_recent_scan.txt 2>&1", + "result": "2 failed in 3.78s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_12.py::test_independent_recent_oracle_proves_no_credit_flag_impossibility", + "tests/test_track_b_insured_status_fix_round_12.py::test_fully_flag_changes_fully_only_against_unflagged_recent_oracle" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "mechanism": "Compile modified module in memory only; source bytes verified unchanged after execution", + "restored": true, + "reproduction_command": "env OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONDONTWRITEBYTECODE=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round12 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round12 PYTHONPATH=\"$PWD/src:$PWD\" /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_12.py::test_independent_recent_oracle_proves_no_credit_flag_impossibility tests/test_track_b_insured_status_fix_round_12.py::test_fully_flag_changes_fully_only_against_unflagged_recent_oracle <<'PY'\n\"\"\"Run named invented-data tests with restricted-file open auditing.\"\"\"\n\nimport hashlib\nimport json\nimport os\nimport sys\nfrom pathlib import Path\n\nROOT = Path(__file__).resolve().parents[2]\nBARRED_NAMES = {\n \"gates.yaml\",\n \"adjusted_poverty.py\",\n \"rows.py\",\n \"ssa_trust_fund_interest_rates_2026.json\",\n \"urban2010_fra68_comparison.md\",\n \"boomers2004_uniform_cut_comparison.md\",\n \"minimum_benefits_comparison.md\",\n \"m6_projection_engine.md\",\n \"mint8_table_user_guide.source.html\",\n \"test_anchor_provenance_erratum.py\",\n}\nCOUNTS = {\"restricted_opens\": 0, \"subprocess.Popen\": 0, \"os.system\": 0}\n\n\ndef audit(event, arguments):\n if event == \"open\" and isinstance(arguments[0], (str, bytes)):\n path = os.fsdecode(arguments[0])\n name = Path(path).name\n if (\n name in BARRED_NAMES\n or name.startswith((\"adjusted_poverty.\", \"rows.\"))\n or \"/PolicyEngine/psid-data/\" in path\n or \"/microcosm-launch-evidence/\" in path\n or \"/dynasim-refs/\" in path\n or \"/claude-501/\" in path\n ):\n COUNTS[\"restricted_opens\"] += 1\n raise RuntimeError(path)\n elif event in (\"subprocess.Popen\", \"os.system\"):\n COUNTS[event] += 1\n\n\ndef main():\n for name in (\n \"POPULACE_DYNAMICS_PSID_DIR\",\n \"POPULACE_DYNAMICS_EPUF_DIR\",\n ):\n assert os.environ[name] == \"/nonexistent/trackb-round12\"\n assert sys.argv[1:]\n assert all(\n not argument.startswith(\"tests/\") or \".py\" in argument\n for argument in sys.argv[1:]\n )\n sys.addaudithook(audit)\n from populace_dynamics.track_b import insured_status as insured\n\n source_path = Path(insured.__file__)\n original = source_path.read_bytes()\n baseline_path = os.environ.get(\"TRACKB_ROUND12_SOURCE\")\n if baseline_path:\n baseline = Path(baseline_path).read_bytes()\n exec(compile(baseline, str(source_path), \"exec\"), insured.__dict__)\n print(\"BASELINE\", hashlib.sha256(baseline).hexdigest(), flush=True)\n spec_path = True\n if spec_path:\n spec = {'name': 'fully_route_without_recent_scan', 'source_sha256': '8ef822d784136ae3b821cb75ec270e945d1972d5cfa10f4ae533fd65f6c0f018', 'changes': [{'before': ' if fully_route and _recent_rule_possible(\\n person, credits, horizon, exit_month\\n ):\\n', 'after': ' if fully_route:\\n'}]}\n assert hashlib.sha256(original).hexdigest() == spec[\"source_sha256\"]\n source = original.decode()\n for change in spec[\"changes\"]:\n assert source.count(change[\"before\"]) == 1, change[\"before\"]\n source = source.replace(change[\"before\"], change[\"after\"], 1)\n exec(compile(source, str(source_path), \"exec\"), insured.__dict__)\n print(\n \"MUTATION\",\n spec[\"name\"],\n \"source_sha256=\" + hashlib.sha256(original).hexdigest(),\n \"mutated_sha256=\" + hashlib.sha256(source.encode()).hexdigest(),\n flush=True,\n )\n import pytest\n\n try:\n result = pytest.main(sys.argv[1:])\n finally:\n assert source_path.read_bytes() == original\n print(\"OPEN_AUDIT\", json.dumps(COUNTS, sort_keys=True), flush=True)\n return result\n\n\nif __name__ == \"__main__\":\n raise SystemExit(main())\nPY" + }, + { + "name": "drop_fully_route_alternate_fallback", + "source_sha256": "8ef822d784136ae3b821cb75ec270e945d1972d5cfa10f4ae533fd65f6c0f018", + "mutated_source_sha256": "7865c679010fa86cefff7cb0ea1747fd5df52da858f07b6daa69aa9ce5d8e68f", + "changes": [ + { + "before": " if _pre1956_alternate_possible(\n person, credits, month, exit_month, lower_credits=lower_credits\n ):\n return True\n if fully_route:\n", + "after": " if not fully_route and _pre1956_alternate_possible(\n person, credits, month, exit_month, lower_credits=lower_credits\n ):\n return True\n if fully_route:\n" + } + ], + "pytest_arguments": [ + "-q", + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "--tb=short", + "tests/test_track_b_insured_status_fix_round_12.py::test_fully_flag_exactness_includes_independent_alternate_oracle" + ], + "command": "env OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONDONTWRITEBYTECODE=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round12 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round12 PYTHONPATH=\"$PWD/src:$PWD\" TRACKB_ROUND12_MUTATION=/Users/maxghenis/.subfleet/worktrees/20261031-164238-trackb-fix-insured-12/scratch/review/round-12-mutation-drop_fully_route_alternate_fallback.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_12_named.py -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_12.py::test_fully_flag_exactness_includes_independent_alternate_oracle > scratch/review/round-12-mutation-drop_fully_route_alternate_fallback.txt 2>&1", + "result": "1 failed in 3.46s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_12.py::test_fully_flag_exactness_includes_independent_alternate_oracle" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "mechanism": "Compile modified module in memory only; source bytes verified unchanged after execution", + "restored": true, + "reproduction_command": "env OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONDONTWRITEBYTECODE=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round12 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round12 PYTHONPATH=\"$PWD/src:$PWD\" /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_12.py::test_fully_flag_exactness_includes_independent_alternate_oracle <<'PY'\n\"\"\"Run named invented-data tests with restricted-file open auditing.\"\"\"\n\nimport hashlib\nimport json\nimport os\nimport sys\nfrom pathlib import Path\n\nROOT = Path(__file__).resolve().parents[2]\nBARRED_NAMES = {\n \"gates.yaml\",\n \"adjusted_poverty.py\",\n \"rows.py\",\n \"ssa_trust_fund_interest_rates_2026.json\",\n \"urban2010_fra68_comparison.md\",\n \"boomers2004_uniform_cut_comparison.md\",\n \"minimum_benefits_comparison.md\",\n \"m6_projection_engine.md\",\n \"mint8_table_user_guide.source.html\",\n \"test_anchor_provenance_erratum.py\",\n}\nCOUNTS = {\"restricted_opens\": 0, \"subprocess.Popen\": 0, \"os.system\": 0}\n\n\ndef audit(event, arguments):\n if event == \"open\" and isinstance(arguments[0], (str, bytes)):\n path = os.fsdecode(arguments[0])\n name = Path(path).name\n if (\n name in BARRED_NAMES\n or name.startswith((\"adjusted_poverty.\", \"rows.\"))\n or \"/PolicyEngine/psid-data/\" in path\n or \"/microcosm-launch-evidence/\" in path\n or \"/dynasim-refs/\" in path\n or \"/claude-501/\" in path\n ):\n COUNTS[\"restricted_opens\"] += 1\n raise RuntimeError(path)\n elif event in (\"subprocess.Popen\", \"os.system\"):\n COUNTS[event] += 1\n\n\ndef main():\n for name in (\n \"POPULACE_DYNAMICS_PSID_DIR\",\n \"POPULACE_DYNAMICS_EPUF_DIR\",\n ):\n assert os.environ[name] == \"/nonexistent/trackb-round12\"\n assert sys.argv[1:]\n assert all(\n not argument.startswith(\"tests/\") or \".py\" in argument\n for argument in sys.argv[1:]\n )\n sys.addaudithook(audit)\n from populace_dynamics.track_b import insured_status as insured\n\n source_path = Path(insured.__file__)\n original = source_path.read_bytes()\n baseline_path = os.environ.get(\"TRACKB_ROUND12_SOURCE\")\n if baseline_path:\n baseline = Path(baseline_path).read_bytes()\n exec(compile(baseline, str(source_path), \"exec\"), insured.__dict__)\n print(\"BASELINE\", hashlib.sha256(baseline).hexdigest(), flush=True)\n spec_path = True\n if spec_path:\n spec = {'name': 'drop_fully_route_alternate_fallback', 'source_sha256': '8ef822d784136ae3b821cb75ec270e945d1972d5cfa10f4ae533fd65f6c0f018', 'changes': [{'before': ' if _pre1956_alternate_possible(\\n person, credits, month, exit_month, lower_credits=lower_credits\\n ):\\n return True\\n if fully_route:\\n', 'after': ' if not fully_route and _pre1956_alternate_possible(\\n person, credits, month, exit_month, lower_credits=lower_credits\\n ):\\n return True\\n if fully_route:\\n'}]}\n assert hashlib.sha256(original).hexdigest() == spec[\"source_sha256\"]\n source = original.decode()\n for change in spec[\"changes\"]:\n assert source.count(change[\"before\"]) == 1, change[\"before\"]\n source = source.replace(change[\"before\"], change[\"after\"], 1)\n exec(compile(source, str(source_path), \"exec\"), insured.__dict__)\n print(\n \"MUTATION\",\n spec[\"name\"],\n \"source_sha256=\" + hashlib.sha256(original).hexdigest(),\n \"mutated_sha256=\" + hashlib.sha256(source.encode()).hexdigest(),\n flush=True,\n )\n import pytest\n\n try:\n result = pytest.main(sys.argv[1:])\n finally:\n assert source_path.read_bytes() == original\n print(\"OPEN_AUDIT\", json.dumps(COUNTS, sort_keys=True), flush=True)\n return result\n\n\nif __name__ == \"__main__\":\n raise SystemExit(main())\nPY" + }, + { + "name": "scan_starts_one_quarter_late", + "source_sha256": "8ef822d784136ae3b821cb75ec270e945d1972d5cfa10f4ae533fd65f6c0f018", + "mutated_source_sha256": "b61d7bbc8c91fc04619d9febed552767ec06092457299cb91dda45b19e047800", + "changes": [ + { + "before": " for quarter in range(_qid(person.disability_onset), _qid(horizon) + 1):\n", + "after": " for quarter in range(_qid(person.disability_onset) + 1, _qid(horizon) + 1):\n" + } + ], + "pytest_arguments": [ + "-q", + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "--tb=short", + "tests/test_track_b_insured_status_fix_round_12.py::test_scan_includes_onset_and_the_earliest_quarter_of_forty" + ], + "command": "env OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONDONTWRITEBYTECODE=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round12 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round12 PYTHONPATH=\"$PWD/src:$PWD\" TRACKB_ROUND12_MUTATION=/Users/maxghenis/.subfleet/worktrees/20261031-164238-trackb-fix-insured-12/scratch/review/round-12-mutation-scan_starts_one_quarter_late.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_12_named.py -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_12.py::test_scan_includes_onset_and_the_earliest_quarter_of_forty > scratch/review/round-12-mutation-scan_starts_one_quarter_late.txt 2>&1", + "result": "1 failed, 1 passed in 1.90s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_12.py::test_scan_includes_onset_and_the_earliest_quarter_of_forty[False]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "mechanism": "Compile modified module in memory only; source bytes verified unchanged after execution", + "restored": true, + "reproduction_command": "env OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONDONTWRITEBYTECODE=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round12 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round12 PYTHONPATH=\"$PWD/src:$PWD\" /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_12.py::test_scan_includes_onset_and_the_earliest_quarter_of_forty <<'PY'\n\"\"\"Run named invented-data tests with restricted-file open auditing.\"\"\"\n\nimport hashlib\nimport json\nimport os\nimport sys\nfrom pathlib import Path\n\nROOT = Path(__file__).resolve().parents[2]\nBARRED_NAMES = {\n \"gates.yaml\",\n \"adjusted_poverty.py\",\n \"rows.py\",\n \"ssa_trust_fund_interest_rates_2026.json\",\n \"urban2010_fra68_comparison.md\",\n \"boomers2004_uniform_cut_comparison.md\",\n \"minimum_benefits_comparison.md\",\n \"m6_projection_engine.md\",\n \"mint8_table_user_guide.source.html\",\n \"test_anchor_provenance_erratum.py\",\n}\nCOUNTS = {\"restricted_opens\": 0, \"subprocess.Popen\": 0, \"os.system\": 0}\n\n\ndef audit(event, arguments):\n if event == \"open\" and isinstance(arguments[0], (str, bytes)):\n path = os.fsdecode(arguments[0])\n name = Path(path).name\n if (\n name in BARRED_NAMES\n or name.startswith((\"adjusted_poverty.\", \"rows.\"))\n or \"/PolicyEngine/psid-data/\" in path\n or \"/microcosm-launch-evidence/\" in path\n or \"/dynasim-refs/\" in path\n or \"/claude-501/\" in path\n ):\n COUNTS[\"restricted_opens\"] += 1\n raise RuntimeError(path)\n elif event in (\"subprocess.Popen\", \"os.system\"):\n COUNTS[event] += 1\n\n\ndef main():\n for name in (\n \"POPULACE_DYNAMICS_PSID_DIR\",\n \"POPULACE_DYNAMICS_EPUF_DIR\",\n ):\n assert os.environ[name] == \"/nonexistent/trackb-round12\"\n assert sys.argv[1:]\n assert all(\n not argument.startswith(\"tests/\") or \".py\" in argument\n for argument in sys.argv[1:]\n )\n sys.addaudithook(audit)\n from populace_dynamics.track_b import insured_status as insured\n\n source_path = Path(insured.__file__)\n original = source_path.read_bytes()\n baseline_path = os.environ.get(\"TRACKB_ROUND12_SOURCE\")\n if baseline_path:\n baseline = Path(baseline_path).read_bytes()\n exec(compile(baseline, str(source_path), \"exec\"), insured.__dict__)\n print(\"BASELINE\", hashlib.sha256(baseline).hexdigest(), flush=True)\n spec_path = True\n if spec_path:\n spec = {'name': 'scan_starts_one_quarter_late', 'source_sha256': '8ef822d784136ae3b821cb75ec270e945d1972d5cfa10f4ae533fd65f6c0f018', 'changes': [{'before': ' for quarter in range(_qid(person.disability_onset), _qid(horizon) + 1):\\n', 'after': ' for quarter in range(_qid(person.disability_onset) + 1, _qid(horizon) + 1):\\n'}]}\n assert hashlib.sha256(original).hexdigest() == spec[\"source_sha256\"]\n source = original.decode()\n for change in spec[\"changes\"]:\n assert source.count(change[\"before\"]) == 1, change[\"before\"]\n source = source.replace(change[\"before\"], change[\"after\"], 1)\n exec(compile(source, str(source_path), \"exec\"), insured.__dict__)\n print(\n \"MUTATION\",\n spec[\"name\"],\n \"source_sha256=\" + hashlib.sha256(original).hexdigest(),\n \"mutated_sha256=\" + hashlib.sha256(source.encode()).hexdigest(),\n flush=True,\n )\n import pytest\n\n try:\n result = pytest.main(sys.argv[1:])\n finally:\n assert source_path.read_bytes() == original\n print(\"OPEN_AUDIT\", json.dumps(COUNTS, sort_keys=True), flush=True)\n return result\n\n\nif __name__ == \"__main__\":\n raise SystemExit(main())\nPY" + }, + { + "name": "scan_stops_one_quarter_early", + "source_sha256": "8ef822d784136ae3b821cb75ec270e945d1972d5cfa10f4ae533fd65f6c0f018", + "mutated_source_sha256": "97ec626446437b06ce39a14529da1a19358a727972f1453ebca0ba27424ff53a", + "changes": [ + { + "before": " for quarter in range(_qid(person.disability_onset), _qid(horizon) + 1):\n", + "after": " for quarter in range(_qid(person.disability_onset), _qid(horizon)):\n" + } + ], + "pytest_arguments": [ + "-q", + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "--tb=short", + "tests/test_track_b_insured_status_fix_round_12.py::test_scan_reaches_last_candidate_quarter_even_with_end_inside_quarter" + ], + "command": "env OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONDONTWRITEBYTECODE=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round12 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round12 PYTHONPATH=\"$PWD/src:$PWD\" TRACKB_ROUND12_MUTATION=/Users/maxghenis/.subfleet/worktrees/20261031-164238-trackb-fix-insured-12/scratch/review/round-12-mutation-scan_stops_one_quarter_early.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_12_named.py -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_12.py::test_scan_reaches_last_candidate_quarter_even_with_end_inside_quarter > scratch/review/round-12-mutation-scan_stops_one_quarter_early.txt 2>&1", + "result": "1 failed, 1 passed in 2.34s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_12.py::test_scan_reaches_last_candidate_quarter_even_with_end_inside_quarter[False]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "mechanism": "Compile modified module in memory only; source bytes verified unchanged after execution", + "restored": true, + "reproduction_command": "env OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONDONTWRITEBYTECODE=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round12 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round12 PYTHONPATH=\"$PWD/src:$PWD\" /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_12.py::test_scan_reaches_last_candidate_quarter_even_with_end_inside_quarter <<'PY'\n\"\"\"Run named invented-data tests with restricted-file open auditing.\"\"\"\n\nimport hashlib\nimport json\nimport os\nimport sys\nfrom pathlib import Path\n\nROOT = Path(__file__).resolve().parents[2]\nBARRED_NAMES = {\n \"gates.yaml\",\n \"adjusted_poverty.py\",\n \"rows.py\",\n \"ssa_trust_fund_interest_rates_2026.json\",\n \"urban2010_fra68_comparison.md\",\n \"boomers2004_uniform_cut_comparison.md\",\n \"minimum_benefits_comparison.md\",\n \"m6_projection_engine.md\",\n \"mint8_table_user_guide.source.html\",\n \"test_anchor_provenance_erratum.py\",\n}\nCOUNTS = {\"restricted_opens\": 0, \"subprocess.Popen\": 0, \"os.system\": 0}\n\n\ndef audit(event, arguments):\n if event == \"open\" and isinstance(arguments[0], (str, bytes)):\n path = os.fsdecode(arguments[0])\n name = Path(path).name\n if (\n name in BARRED_NAMES\n or name.startswith((\"adjusted_poverty.\", \"rows.\"))\n or \"/PolicyEngine/psid-data/\" in path\n or \"/microcosm-launch-evidence/\" in path\n or \"/dynasim-refs/\" in path\n or \"/claude-501/\" in path\n ):\n COUNTS[\"restricted_opens\"] += 1\n raise RuntimeError(path)\n elif event in (\"subprocess.Popen\", \"os.system\"):\n COUNTS[event] += 1\n\n\ndef main():\n for name in (\n \"POPULACE_DYNAMICS_PSID_DIR\",\n \"POPULACE_DYNAMICS_EPUF_DIR\",\n ):\n assert os.environ[name] == \"/nonexistent/trackb-round12\"\n assert sys.argv[1:]\n assert all(\n not argument.startswith(\"tests/\") or \".py\" in argument\n for argument in sys.argv[1:]\n )\n sys.addaudithook(audit)\n from populace_dynamics.track_b import insured_status as insured\n\n source_path = Path(insured.__file__)\n original = source_path.read_bytes()\n baseline_path = os.environ.get(\"TRACKB_ROUND12_SOURCE\")\n if baseline_path:\n baseline = Path(baseline_path).read_bytes()\n exec(compile(baseline, str(source_path), \"exec\"), insured.__dict__)\n print(\"BASELINE\", hashlib.sha256(baseline).hexdigest(), flush=True)\n spec_path = True\n if spec_path:\n spec = {'name': 'scan_stops_one_quarter_early', 'source_sha256': '8ef822d784136ae3b821cb75ec270e945d1972d5cfa10f4ae533fd65f6c0f018', 'changes': [{'before': ' for quarter in range(_qid(person.disability_onset), _qid(horizon) + 1):\\n', 'after': ' for quarter in range(_qid(person.disability_onset), _qid(horizon)):\\n'}]}\n assert hashlib.sha256(original).hexdigest() == spec[\"source_sha256\"]\n source = original.decode()\n for change in spec[\"changes\"]:\n assert source.count(change[\"before\"]) == 1, change[\"before\"]\n source = source.replace(change[\"before\"], change[\"after\"], 1)\n exec(compile(source, str(source_path), \"exec\"), insured.__dict__)\n print(\n \"MUTATION\",\n spec[\"name\"],\n \"source_sha256=\" + hashlib.sha256(original).hexdigest(),\n \"mutated_sha256=\" + hashlib.sha256(source.encode()).hexdigest(),\n flush=True,\n )\n import pytest\n\n try:\n result = pytest.main(sys.argv[1:])\n finally:\n assert source_path.read_bytes() == original\n print(\"OPEN_AUDIT\", json.dumps(COUNTS, sort_keys=True), flush=True)\n return result\n\n\nif __name__ == \"__main__\":\n raise SystemExit(main())\nPY" + }, + { + "name": "scan_counts_candidate_inside_prior_period", + "source_sha256": "8ef822d784136ae3b821cb75ec270e945d1972d5cfa10f4ae533fd65f6c0f018", + "mutated_source_sha256": "16cdc4852f8eaa8cfa42b373fa1bf5e7f6ab66963057ee6f8f307432380d1911", + "changes": [ + { + "before": " if not _outside_prior_periods(person, quarter):\n continue\n", + "after": "" + } + ], + "pytest_arguments": [ + "-q", + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "--tb=short", + "tests/test_track_b_insured_status_fix_round_12.py::test_candidate_inside_prior_period_does_not_supply_recent_witness" + ], + "command": "env OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONDONTWRITEBYTECODE=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round12 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round12 PYTHONPATH=\"$PWD/src:$PWD\" TRACKB_ROUND12_MUTATION=/Users/maxghenis/.subfleet/worktrees/20261031-164238-trackb-fix-insured-12/scratch/review/round-12-mutation-scan_counts_candidate_inside_prior_period.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_12_named.py -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_12.py::test_candidate_inside_prior_period_does_not_supply_recent_witness > scratch/review/round-12-mutation-scan_counts_candidate_inside_prior_period.txt 2>&1", + "result": "1 failed in 1.43s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_12.py::test_candidate_inside_prior_period_does_not_supply_recent_witness" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "mechanism": "Compile modified module in memory only; source bytes verified unchanged after execution", + "restored": true, + "reproduction_command": "env OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONDONTWRITEBYTECODE=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round12 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round12 PYTHONPATH=\"$PWD/src:$PWD\" /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_12.py::test_candidate_inside_prior_period_does_not_supply_recent_witness <<'PY'\n\"\"\"Run named invented-data tests with restricted-file open auditing.\"\"\"\n\nimport hashlib\nimport json\nimport os\nimport sys\nfrom pathlib import Path\n\nROOT = Path(__file__).resolve().parents[2]\nBARRED_NAMES = {\n \"gates.yaml\",\n \"adjusted_poverty.py\",\n \"rows.py\",\n \"ssa_trust_fund_interest_rates_2026.json\",\n \"urban2010_fra68_comparison.md\",\n \"boomers2004_uniform_cut_comparison.md\",\n \"minimum_benefits_comparison.md\",\n \"m6_projection_engine.md\",\n \"mint8_table_user_guide.source.html\",\n \"test_anchor_provenance_erratum.py\",\n}\nCOUNTS = {\"restricted_opens\": 0, \"subprocess.Popen\": 0, \"os.system\": 0}\n\n\ndef audit(event, arguments):\n if event == \"open\" and isinstance(arguments[0], (str, bytes)):\n path = os.fsdecode(arguments[0])\n name = Path(path).name\n if (\n name in BARRED_NAMES\n or name.startswith((\"adjusted_poverty.\", \"rows.\"))\n or \"/PolicyEngine/psid-data/\" in path\n or \"/microcosm-launch-evidence/\" in path\n or \"/dynasim-refs/\" in path\n or \"/claude-501/\" in path\n ):\n COUNTS[\"restricted_opens\"] += 1\n raise RuntimeError(path)\n elif event in (\"subprocess.Popen\", \"os.system\"):\n COUNTS[event] += 1\n\n\ndef main():\n for name in (\n \"POPULACE_DYNAMICS_PSID_DIR\",\n \"POPULACE_DYNAMICS_EPUF_DIR\",\n ):\n assert os.environ[name] == \"/nonexistent/trackb-round12\"\n assert sys.argv[1:]\n assert all(\n not argument.startswith(\"tests/\") or \".py\" in argument\n for argument in sys.argv[1:]\n )\n sys.addaudithook(audit)\n from populace_dynamics.track_b import insured_status as insured\n\n source_path = Path(insured.__file__)\n original = source_path.read_bytes()\n baseline_path = os.environ.get(\"TRACKB_ROUND12_SOURCE\")\n if baseline_path:\n baseline = Path(baseline_path).read_bytes()\n exec(compile(baseline, str(source_path), \"exec\"), insured.__dict__)\n print(\"BASELINE\", hashlib.sha256(baseline).hexdigest(), flush=True)\n spec_path = True\n if spec_path:\n spec = {'name': 'scan_counts_candidate_inside_prior_period', 'source_sha256': '8ef822d784136ae3b821cb75ec270e945d1972d5cfa10f4ae533fd65f6c0f018', 'changes': [{'before': ' if not _outside_prior_periods(person, quarter):\\n continue\\n', 'after': ''}]}\n assert hashlib.sha256(original).hexdigest() == spec[\"source_sha256\"]\n source = original.decode()\n for change in spec[\"changes\"]:\n assert source.count(change[\"before\"]) == 1, change[\"before\"]\n source = source.replace(change[\"before\"], change[\"after\"], 1)\n exec(compile(source, str(source_path), \"exec\"), insured.__dict__)\n print(\n \"MUTATION\",\n spec[\"name\"],\n \"source_sha256=\" + hashlib.sha256(original).hexdigest(),\n \"mutated_sha256=\" + hashlib.sha256(source.encode()).hexdigest(),\n flush=True,\n )\n import pytest\n\n try:\n result = pytest.main(sys.argv[1:])\n finally:\n assert source_path.read_bytes() == original\n print(\"OPEN_AUDIT\", json.dumps(COUNTS, sort_keys=True), flush=True)\n return result\n\n\nif __name__ == \"__main__\":\n raise SystemExit(main())\nPY" + }, + { + "name": "restore_pre1956_flag_early_return", + "source_sha256": "8ef822d784136ae3b821cb75ec270e945d1972d5cfa10f4ae533fd65f6c0f018", + "mutated_source_sha256": "666cae10bd0b01aae72aaaa755f70be03aae0ccee093500f45f8c4936a60deaa", + "changes": [ + { + "before": " if not fully_route and maximum_qcs < 6:\n return False\n", + "after": " if not fully_route and maximum_qcs < 6:\n return False\n if CoverageCondition.DISABILITY_BEFORE_1956 in person.conditions:\n return True\n" + } + ], + "pytest_arguments": [ + "-q", + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "--tb=short", + "tests/test_track_b_insured_status_fix_round_12.py::test_pre1956_flag_cannot_open_a_route_after_1955" + ], + "command": "env OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONDONTWRITEBYTECODE=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round12 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round12 PYTHONPATH=\"$PWD/src:$PWD\" TRACKB_ROUND12_MUTATION=/Users/maxghenis/.subfleet/worktrees/20261031-164238-trackb-fix-insured-12/scratch/review/round-12-mutation-restore_pre1956_flag_early_return.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_12_named.py -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_12.py::test_pre1956_flag_cannot_open_a_route_after_1955 > scratch/review/round-12-mutation-restore_pre1956_flag_early_return.txt 2>&1", + "result": "1 failed in 1.27s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_12.py::test_pre1956_flag_cannot_open_a_route_after_1955" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "mechanism": "Compile modified module in memory only; source bytes verified unchanged after execution", + "restored": true, + "reproduction_command": "env OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONDONTWRITEBYTECODE=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round12 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round12 PYTHONPATH=\"$PWD/src:$PWD\" /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_12.py::test_pre1956_flag_cannot_open_a_route_after_1955 <<'PY'\n\"\"\"Run named invented-data tests with restricted-file open auditing.\"\"\"\n\nimport hashlib\nimport json\nimport os\nimport sys\nfrom pathlib import Path\n\nROOT = Path(__file__).resolve().parents[2]\nBARRED_NAMES = {\n \"gates.yaml\",\n \"adjusted_poverty.py\",\n \"rows.py\",\n \"ssa_trust_fund_interest_rates_2026.json\",\n \"urban2010_fra68_comparison.md\",\n \"boomers2004_uniform_cut_comparison.md\",\n \"minimum_benefits_comparison.md\",\n \"m6_projection_engine.md\",\n \"mint8_table_user_guide.source.html\",\n \"test_anchor_provenance_erratum.py\",\n}\nCOUNTS = {\"restricted_opens\": 0, \"subprocess.Popen\": 0, \"os.system\": 0}\n\n\ndef audit(event, arguments):\n if event == \"open\" and isinstance(arguments[0], (str, bytes)):\n path = os.fsdecode(arguments[0])\n name = Path(path).name\n if (\n name in BARRED_NAMES\n or name.startswith((\"adjusted_poverty.\", \"rows.\"))\n or \"/PolicyEngine/psid-data/\" in path\n or \"/microcosm-launch-evidence/\" in path\n or \"/dynasim-refs/\" in path\n or \"/claude-501/\" in path\n ):\n COUNTS[\"restricted_opens\"] += 1\n raise RuntimeError(path)\n elif event in (\"subprocess.Popen\", \"os.system\"):\n COUNTS[event] += 1\n\n\ndef main():\n for name in (\n \"POPULACE_DYNAMICS_PSID_DIR\",\n \"POPULACE_DYNAMICS_EPUF_DIR\",\n ):\n assert os.environ[name] == \"/nonexistent/trackb-round12\"\n assert sys.argv[1:]\n assert all(\n not argument.startswith(\"tests/\") or \".py\" in argument\n for argument in sys.argv[1:]\n )\n sys.addaudithook(audit)\n from populace_dynamics.track_b import insured_status as insured\n\n source_path = Path(insured.__file__)\n original = source_path.read_bytes()\n baseline_path = os.environ.get(\"TRACKB_ROUND12_SOURCE\")\n if baseline_path:\n baseline = Path(baseline_path).read_bytes()\n exec(compile(baseline, str(source_path), \"exec\"), insured.__dict__)\n print(\"BASELINE\", hashlib.sha256(baseline).hexdigest(), flush=True)\n spec_path = True\n if spec_path:\n spec = {'name': 'restore_pre1956_flag_early_return', 'source_sha256': '8ef822d784136ae3b821cb75ec270e945d1972d5cfa10f4ae533fd65f6c0f018', 'changes': [{'before': ' if not fully_route and maximum_qcs < 6:\\n return False\\n', 'after': ' if not fully_route and maximum_qcs < 6:\\n return False\\n if CoverageCondition.DISABILITY_BEFORE_1956 in person.conditions:\\n return True\\n'}]}\n assert hashlib.sha256(original).hexdigest() == spec[\"source_sha256\"]\n source = original.decode()\n for change in spec[\"changes\"]:\n assert source.count(change[\"before\"]) == 1, change[\"before\"]\n source = source.replace(change[\"before\"], change[\"after\"], 1)\n exec(compile(source, str(source_path), \"exec\"), insured.__dict__)\n print(\n \"MUTATION\",\n spec[\"name\"],\n \"source_sha256=\" + hashlib.sha256(original).hexdigest(),\n \"mutated_sha256=\" + hashlib.sha256(source.encode()).hexdigest(),\n flush=True,\n )\n import pytest\n\n try:\n result = pytest.main(sys.argv[1:])\n finally:\n assert source_path.read_bytes() == original\n print(\"OPEN_AUDIT\", json.dumps(COUNTS, sort_keys=True), flush=True)\n return result\n\n\nif __name__ == \"__main__\":\n raise SystemExit(main())\nPY" + }, + { + "name": "remove_blindness_bypass", + "source_sha256": "8ef822d784136ae3b821cb75ec270e945d1972d5cfa10f4ae533fd65f6c0f018", + "mutated_source_sha256": "61ed9135e4905084d9e4560244f92355fbd2c0d682550fc761062bce42804bd1", + "changes": [ + { + "before": " if fully_route and (\n person.statutory_blindness\n or person.prior_disability_periods_provenance\n is EarningsProvenance.UNKNOWN\n ):\n", + "after": " if fully_route and (\n person.prior_disability_periods_provenance\n is EarningsProvenance.UNKNOWN\n ):\n" + } + ], + "pytest_arguments": [ + "-q", + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "--tb=short", + "tests/test_track_b_insured_status_fix_round_12.py::test_empty_windows_keep_fully_route_blindness_and_unknown_prior_bypasses" + ], + "command": "env OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONDONTWRITEBYTECODE=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round12 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round12 PYTHONPATH=\"$PWD/src:$PWD\" TRACKB_ROUND12_MUTATION=/Users/maxghenis/.subfleet/worktrees/20261031-164238-trackb-fix-insured-12/scratch/review/round-12-mutation-remove_blindness_bypass.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_12_named.py -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_12.py::test_empty_windows_keep_fully_route_blindness_and_unknown_prior_bypasses > scratch/review/round-12-mutation-remove_blindness_bypass.txt 2>&1", + "result": "4 failed, 4 passed in 2.32s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_12.py::test_empty_windows_keep_fully_route_blindness_and_unknown_prior_bypasses[blindness-CoverageCondition.DEEMED_FULLY_INSURED]", + "tests/test_track_b_insured_status_fix_round_12.py::test_empty_windows_keep_fully_route_blindness_and_unknown_prior_bypasses[blindness-CoverageCondition.TRANSITIONAL_INSURED]", + "tests/test_track_b_insured_status_fix_round_12.py::test_empty_windows_keep_fully_route_blindness_and_unknown_prior_bypasses[blindness-CoverageCondition.EARNED_BASIS]", + "tests/test_track_b_insured_status_fix_round_12.py::test_empty_windows_keep_fully_route_blindness_and_unknown_prior_bypasses[blindness-CoverageCondition.SIMPLIFIED_PRE1951]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "mechanism": "Compile modified module in memory only; source bytes verified unchanged after execution", + "restored": true, + "reproduction_command": "env OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONDONTWRITEBYTECODE=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round12 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round12 PYTHONPATH=\"$PWD/src:$PWD\" /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_12.py::test_empty_windows_keep_fully_route_blindness_and_unknown_prior_bypasses <<'PY'\n\"\"\"Run named invented-data tests with restricted-file open auditing.\"\"\"\n\nimport hashlib\nimport json\nimport os\nimport sys\nfrom pathlib import Path\n\nROOT = Path(__file__).resolve().parents[2]\nBARRED_NAMES = {\n \"gates.yaml\",\n \"adjusted_poverty.py\",\n \"rows.py\",\n \"ssa_trust_fund_interest_rates_2026.json\",\n \"urban2010_fra68_comparison.md\",\n \"boomers2004_uniform_cut_comparison.md\",\n \"minimum_benefits_comparison.md\",\n \"m6_projection_engine.md\",\n \"mint8_table_user_guide.source.html\",\n \"test_anchor_provenance_erratum.py\",\n}\nCOUNTS = {\"restricted_opens\": 0, \"subprocess.Popen\": 0, \"os.system\": 0}\n\n\ndef audit(event, arguments):\n if event == \"open\" and isinstance(arguments[0], (str, bytes)):\n path = os.fsdecode(arguments[0])\n name = Path(path).name\n if (\n name in BARRED_NAMES\n or name.startswith((\"adjusted_poverty.\", \"rows.\"))\n or \"/PolicyEngine/psid-data/\" in path\n or \"/microcosm-launch-evidence/\" in path\n or \"/dynasim-refs/\" in path\n or \"/claude-501/\" in path\n ):\n COUNTS[\"restricted_opens\"] += 1\n raise RuntimeError(path)\n elif event in (\"subprocess.Popen\", \"os.system\"):\n COUNTS[event] += 1\n\n\ndef main():\n for name in (\n \"POPULACE_DYNAMICS_PSID_DIR\",\n \"POPULACE_DYNAMICS_EPUF_DIR\",\n ):\n assert os.environ[name] == \"/nonexistent/trackb-round12\"\n assert sys.argv[1:]\n assert all(\n not argument.startswith(\"tests/\") or \".py\" in argument\n for argument in sys.argv[1:]\n )\n sys.addaudithook(audit)\n from populace_dynamics.track_b import insured_status as insured\n\n source_path = Path(insured.__file__)\n original = source_path.read_bytes()\n baseline_path = os.environ.get(\"TRACKB_ROUND12_SOURCE\")\n if baseline_path:\n baseline = Path(baseline_path).read_bytes()\n exec(compile(baseline, str(source_path), \"exec\"), insured.__dict__)\n print(\"BASELINE\", hashlib.sha256(baseline).hexdigest(), flush=True)\n spec_path = True\n if spec_path:\n spec = {'name': 'remove_blindness_bypass', 'source_sha256': '8ef822d784136ae3b821cb75ec270e945d1972d5cfa10f4ae533fd65f6c0f018', 'changes': [{'before': ' if fully_route and (\\n person.statutory_blindness\\n or person.prior_disability_periods_provenance\\n is EarningsProvenance.UNKNOWN\\n ):\\n', 'after': ' if fully_route and (\\n person.prior_disability_periods_provenance\\n is EarningsProvenance.UNKNOWN\\n ):\\n'}]}\n assert hashlib.sha256(original).hexdigest() == spec[\"source_sha256\"]\n source = original.decode()\n for change in spec[\"changes\"]:\n assert source.count(change[\"before\"]) == 1, change[\"before\"]\n source = source.replace(change[\"before\"], change[\"after\"], 1)\n exec(compile(source, str(source_path), \"exec\"), insured.__dict__)\n print(\n \"MUTATION\",\n spec[\"name\"],\n \"source_sha256=\" + hashlib.sha256(original).hexdigest(),\n \"mutated_sha256=\" + hashlib.sha256(source.encode()).hexdigest(),\n flush=True,\n )\n import pytest\n\n try:\n result = pytest.main(sys.argv[1:])\n finally:\n assert source_path.read_bytes() == original\n print(\"OPEN_AUDIT\", json.dumps(COUNTS, sort_keys=True), flush=True)\n return result\n\n\nif __name__ == \"__main__\":\n raise SystemExit(main())\nPY" + }, + { + "name": "remove_unknown_prior_bypass", + "source_sha256": "8ef822d784136ae3b821cb75ec270e945d1972d5cfa10f4ae533fd65f6c0f018", + "mutated_source_sha256": "5cb21399f1531832317716977a89ff812e7ae88579330dd217bffb74c21af0c3", + "changes": [ + { + "before": " if fully_route and (\n person.statutory_blindness\n or person.prior_disability_periods_provenance\n is EarningsProvenance.UNKNOWN\n ):\n", + "after": " if fully_route and person.statutory_blindness:\n" + } + ], + "pytest_arguments": [ + "-q", + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "--tb=short", + "tests/test_track_b_insured_status_fix_round_12.py::test_empty_windows_keep_fully_route_blindness_and_unknown_prior_bypasses" + ], + "command": "env OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONDONTWRITEBYTECODE=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round12 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round12 PYTHONPATH=\"$PWD/src:$PWD\" TRACKB_ROUND12_MUTATION=/Users/maxghenis/.subfleet/worktrees/20261031-164238-trackb-fix-insured-12/scratch/review/round-12-mutation-remove_unknown_prior_bypass.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_12_named.py -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_12.py::test_empty_windows_keep_fully_route_blindness_and_unknown_prior_bypasses > scratch/review/round-12-mutation-remove_unknown_prior_bypass.txt 2>&1", + "result": "4 failed, 4 passed in 5.53s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_12.py::test_empty_windows_keep_fully_route_blindness_and_unknown_prior_bypasses[unknown-prior-CoverageCondition.DEEMED_FULLY_INSURED]", + "tests/test_track_b_insured_status_fix_round_12.py::test_empty_windows_keep_fully_route_blindness_and_unknown_prior_bypasses[unknown-prior-CoverageCondition.TRANSITIONAL_INSURED]", + "tests/test_track_b_insured_status_fix_round_12.py::test_empty_windows_keep_fully_route_blindness_and_unknown_prior_bypasses[unknown-prior-CoverageCondition.EARNED_BASIS]", + "tests/test_track_b_insured_status_fix_round_12.py::test_empty_windows_keep_fully_route_blindness_and_unknown_prior_bypasses[unknown-prior-CoverageCondition.SIMPLIFIED_PRE1951]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "mechanism": "Compile modified module in memory only; source bytes verified unchanged after execution", + "restored": true, + "reproduction_command": "env OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONDONTWRITEBYTECODE=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round12 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round12 PYTHONPATH=\"$PWD/src:$PWD\" /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_12.py::test_empty_windows_keep_fully_route_blindness_and_unknown_prior_bypasses <<'PY'\n\"\"\"Run named invented-data tests with restricted-file open auditing.\"\"\"\n\nimport hashlib\nimport json\nimport os\nimport sys\nfrom pathlib import Path\n\nROOT = Path(__file__).resolve().parents[2]\nBARRED_NAMES = {\n \"gates.yaml\",\n \"adjusted_poverty.py\",\n \"rows.py\",\n \"ssa_trust_fund_interest_rates_2026.json\",\n \"urban2010_fra68_comparison.md\",\n \"boomers2004_uniform_cut_comparison.md\",\n \"minimum_benefits_comparison.md\",\n \"m6_projection_engine.md\",\n \"mint8_table_user_guide.source.html\",\n \"test_anchor_provenance_erratum.py\",\n}\nCOUNTS = {\"restricted_opens\": 0, \"subprocess.Popen\": 0, \"os.system\": 0}\n\n\ndef audit(event, arguments):\n if event == \"open\" and isinstance(arguments[0], (str, bytes)):\n path = os.fsdecode(arguments[0])\n name = Path(path).name\n if (\n name in BARRED_NAMES\n or name.startswith((\"adjusted_poverty.\", \"rows.\"))\n or \"/PolicyEngine/psid-data/\" in path\n or \"/microcosm-launch-evidence/\" in path\n or \"/dynasim-refs/\" in path\n or \"/claude-501/\" in path\n ):\n COUNTS[\"restricted_opens\"] += 1\n raise RuntimeError(path)\n elif event in (\"subprocess.Popen\", \"os.system\"):\n COUNTS[event] += 1\n\n\ndef main():\n for name in (\n \"POPULACE_DYNAMICS_PSID_DIR\",\n \"POPULACE_DYNAMICS_EPUF_DIR\",\n ):\n assert os.environ[name] == \"/nonexistent/trackb-round12\"\n assert sys.argv[1:]\n assert all(\n not argument.startswith(\"tests/\") or \".py\" in argument\n for argument in sys.argv[1:]\n )\n sys.addaudithook(audit)\n from populace_dynamics.track_b import insured_status as insured\n\n source_path = Path(insured.__file__)\n original = source_path.read_bytes()\n baseline_path = os.environ.get(\"TRACKB_ROUND12_SOURCE\")\n if baseline_path:\n baseline = Path(baseline_path).read_bytes()\n exec(compile(baseline, str(source_path), \"exec\"), insured.__dict__)\n print(\"BASELINE\", hashlib.sha256(baseline).hexdigest(), flush=True)\n spec_path = True\n if spec_path:\n spec = {'name': 'remove_unknown_prior_bypass', 'source_sha256': '8ef822d784136ae3b821cb75ec270e945d1972d5cfa10f4ae533fd65f6c0f018', 'changes': [{'before': ' if fully_route and (\\n person.statutory_blindness\\n or person.prior_disability_periods_provenance\\n is EarningsProvenance.UNKNOWN\\n ):\\n', 'after': ' if fully_route and person.statutory_blindness:\\n'}]}\n assert hashlib.sha256(original).hexdigest() == spec[\"source_sha256\"]\n source = original.decode()\n for change in spec[\"changes\"]:\n assert source.count(change[\"before\"]) == 1, change[\"before\"]\n source = source.replace(change[\"before\"], change[\"after\"], 1)\n exec(compile(source, str(source_path), \"exec\"), insured.__dict__)\n print(\n \"MUTATION\",\n spec[\"name\"],\n \"source_sha256=\" + hashlib.sha256(original).hexdigest(),\n \"mutated_sha256=\" + hashlib.sha256(source.encode()).hexdigest(),\n flush=True,\n )\n import pytest\n\n try:\n result = pytest.main(sys.argv[1:])\n finally:\n assert source_path.read_bytes() == original\n print(\"OPEN_AUDIT\", json.dumps(COUNTS, sort_keys=True), flush=True)\n return result\n\n\nif __name__ == \"__main__\":\n raise SystemExit(main())\nPY" + }, + { + "name": "recent_complexity_escapes", + "source_sha256": "8ef822d784136ae3b821cb75ec270e945d1972d5cfa10f4ae533fd65f6c0f018", + "mutated_source_sha256": "900d1017ba32837586023949ab2c0912e809980babd347709c4256e07b953170", + "changes": [ + { + "before": " except InsuredConfigurationUnsupported:\n return True\n return False\n\n\ndef _could_establish_current_period(", + "after": " except InsuredConfigurationUnsupported:\n raise\n return False\n\n\ndef _could_establish_current_period(" + } + ], + "pytest_arguments": [ + "-q", + "-p", + "no:xdist", + "-p", + "no:cacheprovider", + "--tb=short", + "tests/test_track_b_insured_status_fix_round_12.py::test_complexity_preserves_fully_route_reason" + ], + "command": "env OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONDONTWRITEBYTECODE=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round12 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round12 PYTHONPATH=\"$PWD/src:$PWD\" TRACKB_ROUND12_MUTATION=/Users/maxghenis/.subfleet/worktrees/20261031-164238-trackb-fix-insured-12/scratch/review/round-12-mutation-recent_complexity_escapes.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round_12_named.py -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_12.py::test_complexity_preserves_fully_route_reason > scratch/review/round-12-mutation-recent_complexity_escapes.txt 2>&1", + "result": "1 failed in 2.34s", + "exit_code": 1, + "failing_tests": [ + "tests/test_track_b_insured_status_fix_round_12.py::test_complexity_preserves_fully_route_reason" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "mechanism": "Compile modified module in memory only; source bytes verified unchanged after execution", + "restored": true, + "reproduction_command": "env OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONDONTWRITEBYTECODE=1 POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round12 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round12 PYTHONPATH=\"$PWD/src:$PWD\" /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python - -q -p no:xdist -p no:cacheprovider --tb=short tests/test_track_b_insured_status_fix_round_12.py::test_complexity_preserves_fully_route_reason <<'PY'\n\"\"\"Run named invented-data tests with restricted-file open auditing.\"\"\"\n\nimport hashlib\nimport json\nimport os\nimport sys\nfrom pathlib import Path\n\nROOT = Path(__file__).resolve().parents[2]\nBARRED_NAMES = {\n \"gates.yaml\",\n \"adjusted_poverty.py\",\n \"rows.py\",\n \"ssa_trust_fund_interest_rates_2026.json\",\n \"urban2010_fra68_comparison.md\",\n \"boomers2004_uniform_cut_comparison.md\",\n \"minimum_benefits_comparison.md\",\n \"m6_projection_engine.md\",\n \"mint8_table_user_guide.source.html\",\n \"test_anchor_provenance_erratum.py\",\n}\nCOUNTS = {\"restricted_opens\": 0, \"subprocess.Popen\": 0, \"os.system\": 0}\n\n\ndef audit(event, arguments):\n if event == \"open\" and isinstance(arguments[0], (str, bytes)):\n path = os.fsdecode(arguments[0])\n name = Path(path).name\n if (\n name in BARRED_NAMES\n or name.startswith((\"adjusted_poverty.\", \"rows.\"))\n or \"/PolicyEngine/psid-data/\" in path\n or \"/microcosm-launch-evidence/\" in path\n or \"/dynasim-refs/\" in path\n or \"/claude-501/\" in path\n ):\n COUNTS[\"restricted_opens\"] += 1\n raise RuntimeError(path)\n elif event in (\"subprocess.Popen\", \"os.system\"):\n COUNTS[event] += 1\n\n\ndef main():\n for name in (\n \"POPULACE_DYNAMICS_PSID_DIR\",\n \"POPULACE_DYNAMICS_EPUF_DIR\",\n ):\n assert os.environ[name] == \"/nonexistent/trackb-round12\"\n assert sys.argv[1:]\n assert all(\n not argument.startswith(\"tests/\") or \".py\" in argument\n for argument in sys.argv[1:]\n )\n sys.addaudithook(audit)\n from populace_dynamics.track_b import insured_status as insured\n\n source_path = Path(insured.__file__)\n original = source_path.read_bytes()\n baseline_path = os.environ.get(\"TRACKB_ROUND12_SOURCE\")\n if baseline_path:\n baseline = Path(baseline_path).read_bytes()\n exec(compile(baseline, str(source_path), \"exec\"), insured.__dict__)\n print(\"BASELINE\", hashlib.sha256(baseline).hexdigest(), flush=True)\n spec_path = True\n if spec_path:\n spec = {'name': 'recent_complexity_escapes', 'source_sha256': '8ef822d784136ae3b821cb75ec270e945d1972d5cfa10f4ae533fd65f6c0f018', 'changes': [{'before': ' except InsuredConfigurationUnsupported:\\n return True\\n return False\\n\\n\\ndef _could_establish_current_period(', 'after': ' except InsuredConfigurationUnsupported:\\n raise\\n return False\\n\\n\\ndef _could_establish_current_period('}]}\n assert hashlib.sha256(original).hexdigest() == spec[\"source_sha256\"]\n source = original.decode()\n for change in spec[\"changes\"]:\n assert source.count(change[\"before\"]) == 1, change[\"before\"]\n source = source.replace(change[\"before\"], change[\"after\"], 1)\n exec(compile(source, str(source_path), \"exec\"), insured.__dict__)\n print(\n \"MUTATION\",\n spec[\"name\"],\n \"source_sha256=\" + hashlib.sha256(original).hexdigest(),\n \"mutated_sha256=\" + hashlib.sha256(source.encode()).hexdigest(),\n flush=True,\n )\n import pytest\n\n try:\n result = pytest.main(sys.argv[1:])\n finally:\n assert source_path.read_bytes() == original\n print(\"OPEN_AUDIT\", json.dumps(COUNTS, sort_keys=True), flush=True)\n return result\n\n\nif __name__ == \"__main__\":\n raise SystemExit(main())\nPY" + } + ], + "round_12_note": "Ten deliberate isolated in-memory mutations were caught and discarded. All four new generated properties bite, including both recent-rule exactness properties, the alternate oracle, and strict relaxation. Every mutation run audited zero restricted opens or spawned processes and verified original implementation bytes unchanged. Standalone reproduction commands include their own audit hook and exact source pin.", + "round_12_final_source_sha256": "8ef822d784136ae3b821cb75ec270e945d1972d5cfa10f4ae533fd65f6c0f018" } diff --git a/src/populace_dynamics/track_b/insured_status.py b/src/populace_dynamics/track_b/insured_status.py index 1cba66c85..b8c5cea73 100644 --- a/src/populace_dynamics/track_b/insured_status.py +++ b/src/populace_dynamics/track_b/insured_status.py @@ -36,8 +36,10 @@ unknown prior histories and stop at six QCs for blindness. Foreign credits preserve an unmodeled route before every credit-count proof; no totalization minimum or eligibility rule is claimed here. Fully-insured-only flags cannot -bypass an independent recent-credit shortfall, but remain possible below six -actual QCs when that proof does not apply. +bypass a failed recent-rule scan under upper credits, but retain a possible +pre1956 alternate. Blindness and unknown prior history disable that scan. +The declared pre1956 flag adds no route beyond the automatic alternate. +Flag-specific conditions remain declared facts rather than adjudicated rules. Short DIB-entitled prior periods remain possible. Observable specialist credit alternatives cannot silently produce ordinary-only uninsured answers. The query month is a hypothetical entitlement month, not medical or @@ -1112,7 +1114,16 @@ def _assignment(rows, window, boundary): ) -def _witness(person, credits, at, exit_month, kind, *, onset=True): +def _witness( + person, + credits, + at, + exit_month, + kind, + *, + onset=True, + ignore_fully_insured=False, +): end = _qid(at) best = None # Source conflict us:oasdi-insured-prior-disability-favorable-disregard @@ -1224,7 +1235,9 @@ def _witness(person, credits, at, exit_month, kind, *, onset=True): assignment = _assignment(rows, window, boundary) count = len(set(assignment) & set(window)) insured = count >= required and ( - fully if kind is InsuredTest.DISABILITY else True + (fully or ignore_fully_insured) + if kind is InsuredTest.DISABILITY + else True ) score = (insured, count - required, count, rule) candidate = ( @@ -1530,9 +1543,12 @@ def _flagged_establishment_possible(person, years): Fully-route flags change only the fully insured prerequisite, leaving 404.130's independent recent-credit rule standing (404.110-.112; RS00301.101/.106/.470/.475; Act 213(c)). They are handled after that - proof, before the six-QC floor: 404.111 states no numeric minimum. - DISABILITY_BEFORE_1956 replaces the recent test without adding credits - and requires twenty QCs (RS00301.480 A), so it follows both proofs. + numerical proof, and preserve possibility only if a recent rule or the + automatic pre1956 alternate remains possible. They bypass the ordinary + six-QC floor: 404.111 states no numeric minimum. The pre1956 flag adds + no route beyond the automatic alternate (RS00301.480 A/B.1); that + alternate still requires twenty QCs. No flag's own conditions are + adjudicated here. Raw-earnings flags affect compensation or SEI allocation (404.142/.144; RS00301.220/.340/.350). Final direct QC declarations already supply @@ -1590,6 +1606,39 @@ def _minimum_current_period_qcs(person): return min(20, max(6, elapsed // 2)) +def _outside_prior_periods(person, quarter): + """A candidate start must not overlap any declared prior quarter.""" + return all( + not _qid(period.start) <= quarter <= _qid(period.end) + for period in person.prior_disability_periods + ) + + +def _recent_rule_possible(person, credits, horizon, exit_month): + """404.130(b)-(d) possibility, relaxing only the fully prerequisite. + + Upper credits preserve every feasible assignment and favorable prior + treatment. Failure in every eligible quarter therefore disproves all + lower fillings. Complexity cannot disprove a specialist declaration. + """ + try: + for quarter in range(_qid(person.disability_onset), _qid(horizon) + 1): + if not _outside_prior_periods(person, quarter): + continue + if _witness( + person, + credits, + _qdate(quarter), + exit_month, + InsuredTest.DISABILITY, + ignore_fully_insured=True, + )[0]: + return True + except InsuredConfigurationUnsupported: + return True + return False + + def _could_establish_current_period( person, years, @@ -1617,10 +1666,7 @@ def _could_establish_current_period( return True horizon = _current_period_start_horizon(person, month) if person.prior_disability_periods and not any( - all( - not _qid(period.start) <= quarter <= _qid(period.end) - for period in person.prior_disability_periods - ) + _outside_prior_periods(person, quarter) for quarter in range(_qid(person.disability_onset), _qid(horizon) + 1) ): return False @@ -1640,16 +1686,25 @@ def _could_establish_current_period( and maximum_qcs < _minimum_current_period_qcs(person) ): return False - if person.conditions & _FULLY_INSURED_ROUTE_CONDITIONS: + fully_route = bool(person.conditions & _FULLY_INSURED_ROUTE_CONDITIONS) + if fully_route and ( + person.statutory_blindness + or person.prior_disability_periods_provenance + is EarningsProvenance.UNKNOWN + ): return True - if maximum_qcs < 6: + if not fully_route and maximum_qcs < 6: return False - if CoverageCondition.DISABILITY_BEFORE_1956 in person.conditions: + if fully_route and _recent_rule_possible( + person, credits, horizon, exit_month + ): return True if _pre1956_alternate_possible( person, credits, month, exit_month, lower_credits=lower_credits ): return True + if fully_route: + return False rows, _ = _world(person, credits, _qid(horizon), exit_month, False) if sum(len(_assign_qcs(*row)) for row in rows.values()) < 6: return False @@ -1804,7 +1859,11 @@ def insured_status( no totalization minimum or eligibility rule is claimed. A conservative minimum-QC proof precedes fully-insured-only flags and boundary complexity, except for blindness and unknown prior history. Fully-route - flags precede the six-QC floor; the pre-1956 flag follows that floor. + flags bypass the six-QC floor but must retain a recent-rule witness or + automatic pre1956 alternate when that proof applies. Blindness and + unknown prior histories preserve their named flags without this scan. + The pre1956 flag adds no route beyond the automatic alternate. A flag's + own conditions remain declared facts and are not tested. History validation runs first. Uncomputable QC rows use bounded unknown credits only for this proof; a possible declaration retains its original conversion refusal, including its reason and detail. diff --git a/tests/README-tiers.md b/tests/README-tiers.md index 9c2e664a2..95d72212b 100644 --- a/tests/README-tiers.md +++ b/tests/README-tiers.md @@ -39,9 +39,9 @@ pytest --collect-only -q -m oracle_policyengine | tail -1 | Tier | Tests at HEAD | |---|---:| -| `unit` | 20,906 | +| `unit` | 20,971 | | `artifact` | 4,271 | | `integration_psid` | 1,471 | | `reproduction_legacy` | 520 | | `oracle_policyengine` | 308 | -| **Total** | **27,476** | +| **Total** | **27,541** | diff --git a/tests/test_track_b_insured_status_fix_round_12.py b/tests/test_track_b_insured_status_fix_round_12.py new file mode 100644 index 000000000..5cf001850 --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_12.py @@ -0,0 +1,662 @@ +"""Statutory conformance: flags cannot supply missing recent credits. + +Invented declarations only; no population, behavioral, or forecast claim. +The recent-rule oracle enumerates placements with plain quarter arithmetic. +""" + +from dataclasses import replace +from datetime import date, timedelta +from fractions import Fraction +from itertools import combinations, product + +import pytest +from hypothesis import example, given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as i +from populace_dynamics.track_b.gross_benefits import count_family_outcomes +from tests.test_track_b_insured_status import history +from tests.test_track_b_insured_status_fix_round_4_routes import ( + _pre1956_case, +) + +OBSERVED = i.EarningsProvenance.OBSERVED +UNKNOWN = i.EarningsProvenance.UNKNOWN +WEIGHT = Fraction(11, 5) +FULLY_ROUTES = ( + i.CoverageCondition.DEEMED_FULLY_INSURED, + i.CoverageCondition.TRANSITIONAL_INSURED, + i.CoverageCondition.EARNED_BASIS, + i.CoverageCondition.SIMPLIFIED_PRE1951, +) +PRE1956 = i.CoverageCondition.DISABILITY_BEFORE_1956 +RAW = ( + i.CoverageCondition.RAILROAD_CREDITS, + i.CoverageCondition.FISCAL_TAXABLE_YEAR, + i.CoverageCondition.SHORT_TAXABLE_YEAR, +) +CREDIT = ( + i.CoverageCondition.MILITARY_CREDITS, + i.CoverageCondition.MEDICARE_GOVERNMENT_EMPLOYMENT, +) + + +def _person( + *, + birth=date(1960, 2, 2), + onset=date(2000, 1, 15), + end=date(2000, 12, 31), + conditions=(), + **kwargs, +): + return i.Person( + birth, + sex=i.Sex.FEMALE, + disability_onset=onset, + current_disability_period_established=True, + current_disability_period_provenance=OBSERVED, + current_disability_period_end=end, + current_disability_period_end_provenance=OBSERVED, + prior_disability_periods_provenance=OBSERVED, + conditions=conditions, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + **kwargs, + ) + + +def _evaluate(person, years, month=date(2001, 1, 1), **kwargs): + return i.evaluate_insured_status( + "round-twelve-recent-rule", + WEIGHT, + lambda: i.insured_status( + person, years, month, test=i.InsuredTest.FULLY, **kwargs + ), + ) + + +def _refusal(person, years, reason, month=date(2001, 1, 1), **kwargs): + row = _evaluate(person, years, month, **kwargs) + assert row.result is None + assert row.unsupported.reason is reason + counts = count_family_outcomes((row,)) + assert counts.rows == counts.unsupported_rows == 1 + assert counts.weight == counts.unsupported_weight == WEIGHT + return row + + +def _invalid(person, years, month=date(2001, 1, 1), **kwargs): + rows = [] + with pytest.raises(i.InvalidFamilyInput, match="no possible insured"): + rows.append(_evaluate(person, years, month, **kwargs)) + counts = count_family_outcomes(rows) + assert counts.rows == counts.unsupported_rows == 0 + assert counts.weight == counts.unsupported_weight == 0 + + +def _reason(condition): + return i.InsuredUnsupportedReason[condition.name] + + +def _q(value): + return value.year * 4 + (value.month - 1) // 3 + + +def _fixed_history(person, month, quarters, *, end=None): + """All credited quarters here precede 1978, so no placement is hidden.""" + years = history(person, month, end=end) + for year in years: + flags = tuple(year * 4 + quarter in quarters for quarter in range(4)) + assert year < 1978 or not any(flags) + if year < 1978: + years[year] = i.CoverageYear(OBSERVED, qc_quarters=flags) + return years + + +def _recent_oracle( + person, years, horizon, *, exit_month=None, prior_treatment=None +): + """Existence under 404.130(b)-(d), without implementation helpers. + + Annual counts are assigned to every possible eligible set. Each prior + period is considered together with all the others, or all are ignored. + Credited endpoints remain in the clock; uncredited period quarters do + not. Candidate quarters inside any represented prior period are barred. + """ + first_candidate = _q(person.disability_onset) + last_candidate = _q(horizon) + age31 = person.birth_date.replace(year=person.birth_date.year + 31) + age31 -= timedelta(days=1) + age21 = person.birth_date.replace(year=person.birth_date.year + 21) + age21 -= timedelta(days=1) + for candidate in range(first_candidate, last_candidate + 1): + if any( + _q(period.start) <= candidate <= _q(period.end) + for period in person.prior_disability_periods + ): + continue + treatments = ( + (True, False) if person.prior_disability_periods else (True,) + ) + if prior_treatment is not None: + treatments = (prior_treatment,) + for use_periods in treatments: + periods = person.prior_disability_periods if use_periods else () + options = [] + for year, row in years.items(): + last = min( + candidate, + _q(person.death_date) if person.death_date else candidate, + _q(exit_month) if exit_month else candidate, + ) + eligible = tuple( + quarter + for quarter in range(year * 4, year * 4 + 4) + if _q(person.birth_date) <= quarter <= last + and not any( + _q(period.start) < quarter < _q(period.end) + for period in periods + ) + ) + if row.qc_quarters is not None: + fixed = tuple( + year * 4 + quarter + for quarter, flag in enumerate(row.qc_quarters) + if flag and year * 4 + quarter in eligible + ) + options.append((fixed,)) + else: + count = 4 if row.provenance is UNKNOWN else row.qc_count + assert count is not None + options.append( + tuple( + combinations(eligible, min(count, len(eligible))) + ) + ) + for placement in product(*options): + credits = { + quarter for annual in placement for quarter in annual + } + + def allowed(quarter, *, credits=credits, periods=periods): + return not any( + _q(period.start) <= quarter <= _q(period.end) + and quarter not in credits + for period in periods + ) + + ordinary = [] + quarter = candidate + while len(ordinary) < 40: + if allowed(quarter): + ordinary.append(quarter) + quarter -= 1 + if len(credits.intersection(ordinary)) >= 20: + return True + if candidate >= _q(age31) and not any( + period.special_insured + for period in person.prior_disability_periods + ): + continue + elapsed = [ + quarter + for quarter in range( + max(1937 * 4, _q(age21) + 1), candidate + 1 + ) + if allowed(quarter) + ] + if len(elapsed) < 12: + special, needed = ordinary[:12], 6 + elif len(elapsed) > 40: + special, needed = elapsed[-40:], 20 + else: + special, needed = elapsed, max(6, len(elapsed) // 2) + if len(credits.intersection(special)) >= needed: + return True + return False + + +@pytest.mark.parametrize("condition", FULLY_ROUTES) +@pytest.mark.parametrize("total", [19, 20]) +@pytest.mark.parametrize("flagged", [False, True]) +def test_old_lifetime_credits_cannot_supply_any_recent_window( + condition, total, flagged +): + person = _person(conditions=(condition,) if flagged else ()) + counts = {year: 4 for year in range(1978, 1983)} + counts[1982] -= 20 - total + years = history(person, date(2001, 1, 1), counts) + assert not _recent_oracle( + person, years, person.current_disability_period_end + ) + _invalid(person, years) + + +@pytest.mark.parametrize("condition", FULLY_ROUTES) +def test_fully_route_relaxes_only_fully_insured_when_recent_rule_passes( + condition, +): + person = _person(birth=date(1940, 2, 2)) + years = history( + person, date(2001, 1, 1), {year: 4 for year in range(1995, 2000)} + ) + assert _recent_oracle(person, years, person.current_disability_period_end) + _invalid(person, years) + _refusal( + replace(person, conditions=(condition,)), years, _reason(condition) + ) + + +@pytest.mark.parametrize("old_by_one", [False, True]) +def test_scan_includes_onset_and_the_earliest_quarter_of_forty(old_by_one): + person = _person( + birth=date(1910, 2, 2), + onset=date(1962, 1, 15), + end=date(1962, 5, 31), + conditions=(FULLY_ROUTES[0],), + ) + month = date(1968, 1, 1) + onset = 1962 * 4 + credited = set(range(1957 * 4, 1961 * 4 + 3)) + assert len(credited) == 19 + credited.add(onset - 39 - old_by_one) + years = _fixed_history(person, month, credited) + if old_by_one: + _invalid(person, years, month) + else: + _refusal(person, years, _reason(FULLY_ROUTES[0]), month) + + +@pytest.mark.parametrize("after_recovery", [False, True]) +def test_scan_includes_horizon_quarter_and_stops_at_recovery_bound( + after_recovery, +): + person = _person( + birth=date(1910, 2, 2), + onset=date(1962, 1, 15), + end=date(1962, 5, 31), + conditions=(FULLY_ROUTES[0],), + ) + month = date(1968, 1, 1) + credited = set(range(1957 * 4, 1961 * 4 + 3)) + credited.add(1962 * 4 + after_recovery) + years = _fixed_history(person, month, credited) + if after_recovery: + _invalid(person, years, month) + else: + _refusal(person, years, _reason(FULLY_ROUTES[0]), month) + + +@pytest.mark.parametrize("short", [False, True]) +def test_scan_reaches_last_candidate_quarter_even_with_end_inside_quarter( + short, +): + person = _person( + birth=date(1910, 2, 2), + onset=date(1962, 1, 15), + end=date(1962, 8, 31), + conditions=(FULLY_ROUTES[0],), + ) + month = date(1968, 1, 1) + credited = set(range(1957 * 4, 1961 * 4 + 3)) + credited.add(1962 * 4 + (2 if short else 1)) + years = _fixed_history(person, month, credited) + if short: + _invalid(person, years, month) + else: + _refusal(person, years, _reason(FULLY_ROUTES[0]), month) + + +@pytest.mark.parametrize("special", ["under31", "subsequent"]) +@pytest.mark.parametrize("short", [False, True]) +def test_special_recent_requirement_and_one_short(special, short): + prior = ( + () + if special == "under31" + else ( + i.DisabilityPeriod( + date(2010, 1, 1), date(2010, 12, 31), special_insured=True + ), + ) + ) + person = _person( + birth=date(1993 if special == "under31" else 1980, 2, 2), + onset=date(2022, 1, 15), + end=date(2022, 12, 31), + conditions=(FULLY_ROUTES[0],), + prior_disability_periods=prior, + ) + month = date(2023, 1, 1) + required = 16 if special == "under31" else 20 + total = required - short + counts = {} + for year in range(2021, 2005, -1): + counts[year], total = min(total, 4), max(0, total - 4) + years = history(person, month, counts) + assert _recent_oracle( + person, years, person.current_disability_period_end + ) is (not short) + if short: + _invalid(person, years, month) + else: + _refusal(person, years, _reason(FULLY_ROUTES[0]), month) + + +@pytest.mark.parametrize("short", [False, True]) +def test_subsequent_special_recent_rule_can_pass_below_twenty_qcs(short): + person = _person( + birth=date(1990, 2, 2), + onset=date(2022, 1, 15), + end=date(2022, 12, 31), + conditions=(FULLY_ROUTES[0],), + prior_disability_periods=( + i.DisabilityPeriod( + date(2015, 1, 1), date(2017, 12, 31), special_insured=True + ), + ), + ) + month = date(2023, 1, 1) + counts = {year: 4 for year in range(2018, 2022)} + counts[2021] -= short + years = history(person, month, counts) + # After the age-21 quarter, 44 elapsed quarters minus the 12-quarter + # prior period leave 32: Rule III needs 16, while Rule I still needs 20. + assert sum(row.qc_count or 0 for row in years.values()) == 16 - short + assert _recent_oracle(person, years, date(2022, 1, 1)) is (not short) + if short: + _invalid(person, years, month) + else: + _refusal(person, years, _reason(FULLY_ROUTES[0]), month) + + +def _prior_case(*, disregard): + person = _person( + birth=date(1910, 2, 2), + onset=date(1970, 1, 15), + end=date(1970, 12, 31), + conditions=(FULLY_ROUTES[0],), + prior_disability_periods=( + i.DisabilityPeriod(date(1960, 1, 1), date(1965, 12, 31)), + ), + ) + month = date(1973, 1, 1) + if disregard: + credited = set(range(1961 * 4, 1966 * 4)) + else: + credited = set(range(1955 * 4, 1960 * 4)) + return person, _fixed_history(person, month, credited), month + + +@pytest.mark.parametrize("disregard", [False, True]) +def test_recent_window_uses_all_prior_periods_or_disregards_all(disregard): + person, years, month = _prior_case(disregard=disregard) + assert _recent_oracle(person, years, date(1970, 10, 1)) + assert _recent_oracle( + person, years, date(1970, 10, 1), prior_treatment=not disregard + ) + assert not _recent_oracle( + person, years, date(1970, 10, 1), prior_treatment=disregard + ) + _refusal(person, years, _reason(FULLY_ROUTES[0]), month) + + +def test_candidate_inside_prior_period_does_not_supply_recent_witness(): + person = _person( + birth=date(1910, 2, 2), + onset=date(1970, 2, 15), + end=date(1970, 12, 31), + conditions=(FULLY_ROUTES[0],), + prior_disability_periods=( + i.DisabilityPeriod(date(1960, 1, 1), date(1970, 1, 31)), + ), + ) + month = date(1973, 1, 1) + # Disregard yields twenty at the overlapped onset quarter only. The + # first of those QCs ages out before the first usable candidate. + credited = {1960 * 4 + 1, *range(1965 * 4, 1969 * 4 + 3)} + years = _fixed_history(person, month, credited) + assert not _recent_oracle(person, years, date(1970, 10, 1)) + _invalid(person, years, month) + + +@pytest.mark.parametrize("condition", FULLY_ROUTES) +def test_fully_route_keeps_alternate_when_ordinary_recent_rule_is_closed( + condition, +): + person, years, month = _pre1956_case() + person = replace(person, conditions=(condition,)) + assert not _recent_oracle(person, years, person.disability_onset) + _refusal(person, years, _reason(condition), month) + + +@pytest.mark.parametrize("condition", FULLY_ROUTES) +@pytest.mark.parametrize("exception", ["blindness", "unknown-prior"]) +def test_empty_windows_keep_fully_route_blindness_and_unknown_prior_bypasses( + condition, exception +): + person = _person(conditions=(condition,)) + if exception == "blindness": + person = replace(person, statutory_blindness=True) + else: + person = replace(person, prior_disability_periods_provenance=UNKNOWN) + years = history(person, date(2001, 1, 1)) + _refusal(person, years, _reason(condition)) + + +@pytest.mark.parametrize("condition", FULLY_ROUTES) +def test_unknown_recent_years_and_every_surviving_filling_keep_flag_reason( + condition, +): + person = _person(conditions=(condition,)) + years = history( + person, date(2001, 1, 1), {year: 4 for year in range(1995, 1999)} + ) + years[1999] = i.CoverageYear(UNKNOWN) + _refusal(person, years, _reason(condition)) + for count in range(5): + filling = {**years, 1999: i.CoverageYear(OBSERVED, qc_count=count)} + if count == 4: + _refusal(person, filling, _reason(condition)) + else: + _invalid(person, filling) + + +def test_deferred_conversion_keeps_original_refusal_with_possible_recent_rule(): + person = _person( + birth=date(1900, 2, 2), + onset=date(1957, 1, 15), + end=date(1957, 12, 31), + conditions=(FULLY_ROUTES[0],), + ) + month = date(1968, 1, 1) + years = history(person, month, {year: 4 for year in range(1952, 1957)}) + years[1937] = i.CoverageYear(OBSERVED, quarterly_wages=(Fraction(50),) * 4) + _refusal(person, years, i.InsuredUnsupportedReason.EARNINGS_1937, month) + + +def test_pre1956_flag_cannot_open_a_route_after_1955(): + person = _person(conditions=(PRE1956,)) + years = history( + person, date(2001, 1, 1), {year: 4 for year in range(1978, 1983)} + ) + _invalid(person, years) + + +def test_pre1956_flag_keeps_named_refusal_when_alternate_conditions_hold(): + person, years, month = _pre1956_case() + _refusal( + replace(person, conditions=(PRE1956,)), years, _reason(PRE1956), month + ) + + +def test_pre1956_flag_keeps_named_refusal_when_ordinary_route_is_open(): + person = _person(conditions=(PRE1956,)) + years = history( + person, date(2001, 1, 1), {year: 4 for year in range(1995, 2000)} + ) + _refusal(person, years, _reason(PRE1956)) + + +def test_complexity_preserves_fully_route_reason(): + periods = tuple( + i.DisabilityPeriod(date(year, 1, 1), date(year, 6, 30)) + for year in range(1980, 1988) + ) + person = _person( + conditions=(FULLY_ROUTES[0],), prior_disability_periods=periods + ) + counts = {year: 2 for year in range(1980, 1988)} + counts[1999] = 4 + years = history(person, date(2001, 1, 1), counts) + _refusal(person, years, _reason(FULLY_ROUTES[0])) + + +@pytest.mark.parametrize("condition", (*CREDIT, *RAW)) +def test_credit_and_unbounded_raw_earnings_flags_can_add_recent_credits( + condition, +): + person = _person(conditions=(condition,)) + years = history(person, date(2001, 1, 1)) + if condition in RAW: + years[1999] = i.CoverageYear(OBSERVED, wages=Fraction(0)) + _refusal(person, years, _reason(condition)) + + +@settings(max_examples=48, deadline=None) +@example(age=29, recent=0, old=20, condition=FULLY_ROUTES[0]) +@example(age=42, recent=0, old=20, condition=PRE1956) +@given( + age=st.sampled_from([24, 29, 31, 42]), + recent=st.integers(0, 24), + old=st.integers(0, 24), + condition=st.sampled_from((*FULLY_ROUTES, *RAW, PRE1956)), +) +def test_independent_recent_oracle_proves_no_credit_flag_impossibility( + age, recent, old, condition +): + person = _person( + birth=date(2022 - age, 2, 2), + onset=date(2022, 1, 15), + end=date(2022, 12, 31), + conditions=(condition,), + ) + counts = {} + for year in range(2021, 2015, -1): + counts[year], recent = min(recent, 4), max(0, recent - 4) + # Older QCs are outside every candidate 40-quarter window. Some young + # records have no room for this old history and simply retain zero. + for year in range(2009, max(1937, person.birth_date.year) - 1, -1): + counts[year], old = min(old, 4), max(0, old - 4) + month = date(2023, 1, 1) + years = history(person, month, counts) + possible = _recent_oracle( + person, years, person.current_disability_period_end + ) + if not possible: + _invalid(person, years, month) + elif condition in FULLY_ROUTES: + _refusal(person, years, _reason(condition), month) + + +@settings(max_examples=40, deadline=None) +@example(age=42, recent=0, old=24, condition=FULLY_ROUTES[0]) +@example(age=60, recent=20, old=0, condition=FULLY_ROUTES[0]) +@given( + age=st.sampled_from([24, 29, 42, 60]), + recent=st.integers(0, 24), + old=st.integers(0, 24), + condition=st.sampled_from(FULLY_ROUTES), +) +def test_fully_flag_changes_fully_only_against_unflagged_recent_oracle( + age, recent, old, condition +): + person = _person( + birth=date(2022 - age, 2, 2), + onset=date(2022, 1, 15), + end=date(2022, 12, 31), + ) + counts = {} + for year in range(2021, 2015, -1): + counts[year], recent = min(recent, 4), max(0, recent - 4) + for year in range(2009, max(1937, person.birth_date.year) - 1, -1): + counts[year], old = min(old, 4), max(0, old - 4) + month = date(2023, 1, 1) + years = history(person, month, counts) + recent_possible = _recent_oracle( + person, years, person.current_disability_period_end + ) + flagged = replace(person, conditions=(condition,)) + if recent_possible: + _refusal(flagged, years, _reason(condition), month) + else: + _invalid(flagged, years, month) + + +@settings(max_examples=40, deadline=None) +@example(age=60, count=4, quarter=0) +@given( + age=st.sampled_from([24, 29, 42, 60]), + count=st.integers(0, 4), + quarter=st.integers(0, 3), +) +def test_witness_keyword_only_relaxes_fully_prerequisite(age, count, quarter): + person = _person( + birth=date(2022 - age, 2, 2), + onset=date(2022, 1, 15), + end=date(2022, 12, 31), + ) + years = history( + person, date(2023, 1, 1), {year: count for year in range(2017, 2022)} + ) + credits = { + year: i._credits(year, row, True) for year, row in years.items() + } + at = date(2022, quarter * 3 + 1, 1) + ordinary = i._witness(person, credits, at, None, i.InsuredTest.DISABILITY) + relaxed = i._witness( + person, + credits, + at, + None, + i.InsuredTest.DISABILITY, + ignore_fully_insured=True, + ) + assert not ordinary[0] or relaxed[0] + assert relaxed[1:] == ordinary[1:] + # An explicit divergent surface makes a no-op keyword fail too. + if age == 60 and count == 4: + assert not ordinary[0] and relaxed[0] + + +@settings(max_examples=40, deadline=None) +@example(old=14, continuous=6, condition=FULLY_ROUTES[0]) +@example(old=13, continuous=6, condition=FULLY_ROUTES[0]) +@given( + old=st.integers(0, 16), + continuous=st.integers(0, 6), + condition=st.sampled_from(FULLY_ROUTES), +) +def test_fully_flag_exactness_includes_independent_alternate_oracle( + old, continuous, condition +): + person = _person( + birth=date(1900, 2, 2), + onset=date(1952, 7, 15), + end=date(1953, 12, 31), + conditions=(condition,), + ) + month = date(1968, 1, 1) + credited = set(range(1938 * 4, 1938 * 4 + old)) + credited.update(range(1951 * 4, 1951 * 4 + continuous)) + years = _fixed_history(person, month, credited) + recent_possible = _recent_oracle(person, years, date(1953, 10, 1)) + assert not recent_possible + # RS00301.480 B.1 opens in July 1952. With these fixed records the + # only possible continuous clock consists of 1951Q1 through 1952Q2; + # every later clock contains an uncredited quarter. Old QCs are all + # outside 40-quarter windows, and cannot exclude the alternate. + alternate_possible = old + continuous >= 20 and continuous == 6 + if recent_possible or alternate_possible: + _refusal(person, years, _reason(condition), month) + else: + _invalid(person, years, month) diff --git a/tests/tier_counts.json b/tests/tier_counts.json index 1cf03c498..fe674b50e 100644 --- a/tests/tier_counts.json +++ b/tests/tier_counts.json @@ -1,7 +1,7 @@ { "schema_version": 1, "counts": { - "unit": 20906, + "unit": 20971, "artifact": 4271, "integration_psid": 1471, "reproduction_legacy": 520, From aee9d4a7a7c5607be00f8ef01bdacb01e1477263 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sat, 31 Oct 2026 18:51:25 -0400 Subject: [PATCH 18/46] Require one feasible insured-period completion across credits and starts (#562 round 13) Sol's ninth review found two medium gaps, and this round's independent oracle found more of the same class. A "possible" current period has to mean one filling, one prior treatment and one start that meet every constraint at once. Several proofs tested those constraints separately. - The six-QC floor now counts credits feasible by the start horizon and runs before the UNKNOWN-prior return. Missing prior history can move a window but can't remove the floor. Only blindness with a fully-route flag passes it. - UNKNOWN priors face a joint proof on an optimistic clock. It deletes every uncredited quarter after the earliest possible prior and keeps every QC, so it dominates any number of real prior periods. A Rule III prior needs six QCs before age 31 under 404.130(c) and (d). Past blindness stays open, because statutory_blindness=False says nothing about the past. - 404.321(a) fixes the start at onset if insured then, otherwise at the first later insured quarter. A later clear quarter can't repair an earlier start inside a prior period, so the fully-route scan enumerates fillings and tests each one's first insured start. - The pre-1956 alternate's start must also clear prior-period overlap. - The ordinary constructor retries annual placements when the favorable one overlaps a prior. The selected filling and treatment also supply the DISABILITY witness, so the output agrees with the start. The new classification oracle enumerates completions in plain arithmetic, without calling the rule's proofs, across 4,819 declarations plus generated cases. Its header states its bounds. It found the defects above, including one false rejection from greedy annual placement. One existing test changes. It pinned six QCs at age 40 as a named refusal under UNKNOWN priors, but no filling reaches a route there: Rule III needs six QCs before 31, and six lifetime QCs can't supply 20/40. Those credits now raise InvalidFamilyInput, and six QCs at ages 22 and 23 keep the named refusal. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 177 ++- .../track_b_insured_status_mutations.json | 529 +++++++- .../track_b/insured_status.py | 374 +++++- tests/README-tiers.md | 4 +- ..._b_insured_status_classification_oracle.py | 1188 +++++++++++++++++ ...est_track_b_insured_status_fix_round_11.py | 24 +- ...est_track_b_insured_status_fix_round_12.py | 7 +- ...est_track_b_insured_status_fix_round_13.py | 317 +++++ tests/tier_counts.json | 2 +- 9 files changed, 2534 insertions(+), 88 deletions(-) create mode 100644 tests/test_track_b_insured_status_classification_oracle.py create mode 100644 tests/test_track_b_insured_status_fix_round_13.py diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index fe055f5c4..3ddcb4301 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -244,24 +244,36 @@ lower bound too high (404.130(a)–(f); RS .480 A). Blindness uses the fully insured prerequisite alone (`blindness_fully_only`), so it disables the stronger proof. UNKNOWN prior history can supply -additional exclusions and also disables that proof. A fully-route flag -preserves its named refusal in either case, even below six actual QCs: -its unmodeled fully insured rule may replace that ordinary prerequisite. -With known prior history and no blindness, the flag instead needs a +additional exclusions and also disables that proof. The next proof counts +maximum feasible QCs by the immutable start horizon, respecting death and +coverage exit. Fewer than six proves impossibility even with UNKNOWN +prior history and a fully-route flag. Section 404.130(b) requires twenty; +(c) and (d) retain at least six; (f) changes elapsed quarters rather than +that floor; RS .480 also requires twenty. Blindness with a fully-route +flag alone bypasses this proof because 404.130(e) has no recent-credit +test and the flag presumes its fully insured prerequisite. Blindness +without that flag still needs six ordinary fully insured QCs. +With known prior history and no blindness, a fully-route flag also needs a possible recent rule in a nonoverlapping starting quarter from onset through the immutable horizon, or a possible automatic pre1956 alternate. -The recent scan uses the same assignment, all-period use/disregard, and -special-window rules as the ordinary witness, relaxing only its fully -insured prerequisite (404.130(a)–(d), (f)). If maximum feasible credits +The recent scan uses the same annual assignment, fixed all-period +use/disregard treatment, and special-window rules as the ordinary witness, +relaxing only its fully insured prerequisite (404.130(a)–(d), (f)). If maximum feasible credits cannot satisfy any such recent rule and the alternate is unavailable, no lower-credit filling can establish the period. A fully-route flag changes neither constraint. A complexity refusal during this scan preserves possibility so that the flag retains its own named refusal. -Without a fully-route flag, the ordinary six-QC floor still precedes the -automatic alternate. The pre1956 alternate needs 20 QCs (RS .480 A) and +The horizon six-QC floor precedes the automatic alternate. The pre1956 +alternate needs 20 QCs (RS .480 A) and an eligible start no later than December 31, 1955 (RS .480 B.1). Its -explicit flag adds no credit, condition, or route beyond the automatic +establishment witness uses one quarter satisfying that date limit, the +immutable horizon, and fixed prior-period nonoverlap together. A clear +post-1955 quarter cannot validate a different, overlapping alternate +start. This start check applies only to a declared established period; +the continuous clock still uses or disregards all prior periods and +retains credited endpoints. The lower-credit 20/40 exclusion is unchanged. +Its explicit flag adds no credit, condition, or route beyond the automatic check and therefore supplies no separate early return. Any declaration that survives establishment validation still receives the flag's named refusal. The rule does not test a flag's own conditions: for example, a @@ -588,9 +600,11 @@ refusals. Within those checks, fixed-quarter overlap comes first, followed by declared foreign credits and any credit-route flag or raw-earnings flag without a complete direct-QC envelope. The known-history nonblind minimum-requirement proof follows before every boundary enumeration. -A fully-route flag then preserves possibility immediately for blindness -or UNKNOWN prior history. Without that flag, fewer than six maximum QCs -proves impossibility. Otherwise a fully-route flag needs a recent-rule +A fully-route flag then preserves possibility immediately for blindness. +Otherwise fewer than six maximum QCs feasible by the immutable start +horizon proves impossibility, including UNKNOWN prior history. After +that floor, a fully-route flag preserves possibility for UNKNOWN priors; +with known priors it needs a recent-rule witness from onset through the horizon, or the automatic pre1956 alternate. Neither route means impossibility even with that flag. An explicit `DISABILITY_BEFORE_1956` flag supplies no separate route or early @@ -662,11 +676,11 @@ unreachable 404.112 birth cohort does not invalidate an explicitly declared | Flag | Captured premise and effect | Class | | --- | --- | --- | -| `DEEMED_FULLY_INSURED` | RS .106 B.2 says "deemed fully insured for all title II purposes"; 404.110(a), .111, .112 and RS .470 concern the fully insured prerequisite. | Fully route | +| `DEEMED_FULLY_INSURED` | RS .106 B.2 says "deemed fully insured for all title II purposes"; 404.110(a), .111, .112 and RS .470 concern the fully insured prerequisite. Every fully route retains the horizon six-QC floor except with statutory blindness (404.130(b)–(e)); UNKNOWN priors cannot remove it. | Fully route | | `TRANSITIONAL_INSURED` | RS .101 B.1 lists "Transitional Insured Status" beside fully insured status for spouse benefits. It is absent from 404.130's four rules and supplies no recent QC. | Fully route | | `EARNED_BASIS` | RS .475 A says "fully insured status could be established by crediting certain wages on an earned rather than a paid basis". Its stated special method changes the fully insured prerequisite. | Fully route | | `SIMPLIFIED_PRE1951` | Act 213(c) says "For purposes of sections 414(a) and 415(d)"; 404.110(d)(1) says "For purposes of paragraph (b) of this section". Simplified credits affect fully insured status, not the independent recent test. | Fully route | -| `DISABILITY_BEFORE_1956` | RS .480 A requires "at least 20 quarters of coverage (QC) by the end of that quarter", the continuous-QC clock, and an eligible historical start; B.1 says "the last day on which it can begin is 12/31/55". The flag adds no credit or route beyond the automatic alternate check. A surviving declaration retains its named refusal. | Recent test | +| `DISABILITY_BEFORE_1956` | RS .480 A requires "at least 20 quarters of coverage (QC) by the end of that quarter", the continuous-QC clock, and an eligible historical start; B.1 says "the last day on which it can begin is 12/31/55". For established periods that same start must clear prior-period overlap and the immutable horizon. The flag adds no credit or route beyond the automatic alternate check. A surviving declaration retains its named refusal. | Recent test | | `RAILROAD_CREDITS` | RS .350 A says "we may use RR compensation in determining the number of quarters of coverage (QCs)"; RS .131 also identifies freeze credits. Compensation can add QCs before a final direct-QC declaration. | Raw earnings | | `FISCAL_TAXABLE_YEAR` | RS .220 says "we will allocate the SEI proportionately to the two calendars years"; 404.142 and .144 govern taxable-year allocation. The rule acts on earnings, not an already declared final QC count. | Raw earnings | | `SHORT_TAXABLE_YEAR` | RS .340 B.2.b says "credit SEI equally to the calendar quarter in which the TY ends" and preceding quarters in the taxable year; 404.142 and .144 govern allocation. | Raw earnings | @@ -681,9 +695,10 @@ are excluded from that contract because 404.133 expressly gives freeze-only credits. Fully-route flags remain below the numerical recent-credit proof and, with known prior history and no blindness, the candidate-quarter recent scan. They bypass only the ordinary fully insured prerequisite and -its six-QC floor. Their named refusals survive blindness or UNKNOWN prior -history, where the recent proof is inapplicable, and any case with a -possible recent or automatic alternate route. The pre1956 flag still obeys +its ordinary fully insured floor. Their named refusals survive blindness +at a clear onset, or UNKNOWN prior history surviving the horizon floor +and joint optimistic-clock proof, and any case with a possible first +recent or automatic alternate start. The pre1956 flag still obeys the ordinary six-QC floor and automatic alternate conditions because it adds no credit or route. @@ -787,22 +802,24 @@ to a statutory sentence that does not state it. | I6. An alien worker's actual pre2004 SSN assignment conflicts with declared SSPA applicability; birth on/after January 1, 2004 conflicts with declared exemption. Both never-assigned and an assigned SSN, or assignment before birth, remain invalid. A worker born before 2004 may pair a post2003 assignment or never-assigned status with an adjudicated exemption. | RS .102 B.1 says an alien assigned an SSN before 2004 "is exempt", including a nonwork SSN. B.3.b says, "If an alien worker could have legitimately been assigned an SSN before 1/1/2004, the worker is exempt from the requirements of section 211 of the SSPA." Its wrong-number SS-5 scenario issued another person's number "instead of assigning the alien worker their own SSN". Thus observed or convention-filled exemption overrides either later-assignment or never-assigned presumptions when legitimate pre2004 assignment was possible. Birth on/after January 1, 2004 rules out that exception independently of the assignment record. B.4.b's worker without an SSN "is nevertheless considered to meet the work SSN requirement" when work-authorized; meeting that requirement alone supplies no exemption. | | I7. Explicit quarterly QCs or positive quarterly wages cannot occur before birth, after the query/coverage-end quarter, or after the death quarter. Every required coverage year is declared exactly once through the earliest query, exit, or death year. | A213(a)(2)(B)(i), (v): "no quarter after the quarter in which an individual dies" and "no quarter shall be counted ... prior to the beginning of such quarter"; B404.146(a)-(b) agree. Birth and supplied-record exit caps, complete years, and no implicit zeros are interface premises. Annual counts are capped rather than dated after exit. Specialist earned-basis or additional-credit declarations remain refusals and do not reinterpret an explicit ordinary covered-quarter declaration. | | I8. A declared current establishment is invalid only after the shared possibility check excludes every route and every feasible prior/earnings filling. One ordinary filling must satisfy its insured start, recovery or administrative end, continuity, and overlap constraints together. | C320(b)(2) requires insured disability "in the calendar quarter in which you became disabled, or in a later calendar quarter"; C321(a) chooses the first such quarter. B404.130(a) supplies four ordinary rules and RS .480 supplies the alternate historical rule. The start horizon uses an inferred recovery month when I14 permits one, otherwise the declared end, together with continuity/query/death/FRA caps. Maximum credits establish only monotone insurance by that fixed horizon. A derived prior-quarter overlap requires a single lower-credit or enumerated filling whose first start also clears that overlap. An ordinary or alternate witness after the horizon cannot supply possibility. Foreign credits and the flag classes determine which credit-count proofs apply, in the refusal order above, before any alternate or boundary enumeration. The alternate's 20/40 exclusion instead uses U10's earliest date shared by every completion; a later witness cannot prove impossibility under every defensible reading of RS .480 A. | -| I9. Without a fully-route flag, fewer than six maximum feasible ordinary lifetime QCs proves current establishment impossible only after foreign credits, credit-route flags, and unresolved raw-earnings flags have preserved their possible routes. | B404.110(b)(1): "You need at least 6 QCs but not more than 40 QCs"; B404.130(a): "you must be fully insured". The flag table supplies each exception's captured premise. A record composed entirely of direct final QC declarations (`qc_count` or `qc_quarters`) and UNKNOWN years fixes or bounds all admissible final credits from RR compensation and fiscal/short taxable-year allocation. This is the direct-credit input contract, not a claim that ordinary RSDI credits exhaust freeze-only military credits: B404.133 expressly supplies the latter, so `MILITARY_CREDITS` remains a separate credit route even with direct rows. Any raw row leaves the raw-earnings route unresolved. Period exclusions alone cannot add ordinary QCs. RS .480 A separately requires 20 QCs and the explicit `DISABILITY_BEFORE_1956` flag adds no route beyond the automatic alternate, so it cannot rescue a below-six declaration. Fully-route flags bypass this fully insured floor but still obey I15 and I16 where applicable. No ordinary floor applies to the unmodeled foreign-credit route (U11). | +| I9. Except for blindness with a fully-route flag, fewer than six maximum feasible QCs by the immutable start horizon proves current establishment impossible after foreign credits, credit-route flags, and unresolved raw-earnings flags have preserved their possible routes. | B404.110(b)(1): "You need at least 6 QCs but not more than 40 QCs"; B404.130(a): "you must be fully insured". The flag table supplies each exception's captured premise. A record composed entirely of direct final QC declarations (`qc_count` or `qc_quarters`) and UNKNOWN years fixes or bounds all admissible final credits from RR compensation and fiscal/short taxable-year allocation. This is the direct-credit input contract, not a claim that ordinary RSDI credits exhaust freeze-only military credits: B404.133 expressly supplies the latter, so `MILITARY_CREDITS` remains a separate credit route even with direct rows. Any raw row leaves the raw-earnings route unresolved. Period exclusions alone cannot add ordinary QCs. RS .480 A separately requires 20 QCs and the explicit `DISABILITY_BEFORE_1956` flag adds no route beyond the automatic alternate, so it cannot rescue a below-six declaration. Fully-route flags replace only the fully insured prerequisite; nonblind recent rules retain the universal horizon floor in I17, even under UNKNOWN prior history. Blindness with a fully-route flag bypasses that floor under 404.130(e). No ordinary floor applies to the unmodeled foreign-credit route (U11). | | I10. The supported calendar, mandatory historical sex, and explicit establishment declaration must be supplied: birth years 1870–9900, query years through 9990, sex for births before January 2, 1913, and establishment provenance whenever onset is present. | These are interface-domain requirements. B404.110(b)(2) and .132 apply different historical male/female endpoints; B404.110(c) excludes only a period "we established for you". Missing facts are not inferred. Calendar limits reserve space for date arithmetic and assert no legal incapacity outside the implementation domain; alternative credit routes cannot supply missing declared facts. | | I11. A continues-through observation requires established disability, cannot precede medical onset or the first feasible insured start, cannot exceed the pre-FRA or death boundary, and cannot follow a declared administrative end. | C320(b)(2) and C321(a) require the insured start; A216(i)(2)(D) and C321(c) bound the period's end. A declaration that a period was in force on a date requires that date to lie within one possible period. This is a dated observation, not an asserted ending; a date later than the query is allowed. Provenance and convention identifiers follow the existing fact schema. | | I12. A raw-credit conversion refusal cannot hide established-period impossibility that every feasible filling of that row preserves. | C320(b)(2), C321(a), and B404.110(b)(1) supply the insured-start and six-QC premises. The #530 input contract puts input errors before coverage refusals. Schema validation remains first; the four conversion refusals are deferred only for this proof, with unresolved rows bounded by feasible ordinary quarters. A surviving filling preserves the original refusal reason and note rather than manufacturing a supported status. | | I13. If no starting quarter from onset through the immutable horizon clears all supplied prior-period quarters, current establishment is impossible independently of credit fillings, their count, or a specialist route. | C320(b)(2) and C321(a) require an insured beginning within that interval; I4's nonoverlapping-quarter representation applies to that same beginning. A credit route cannot move a candidate outside the fixed interval or remove a supplied prior quarter. This fixed contradiction is checked before specialist possibility and filling enumeration; it does not treat UNKNOWN prior history as supplied empty history. | | I14. A declared recovery-only historical end implies a recovery month two months earlier; recovery before the onset month or a derived start after that month is invalid. | C321(b) ends the period on "the last day of the second month following the month in which your disability ended". C320(b)(2) and B404.131(a) require an insured quarter in which the worker was disabled, so an administrative grace month cannot supply a new disabled quarter. The helper returns no recovery inference for an end on/after February 1, 1981, in/after the month preceding FRA, or in/after the death month. These carve-outs preserve the existing validity horizon and make no claim about paragraph (c) recovery or administrative ending rules. | -| I15. With known prior history, no blindness, no foreign credits, no credit-route flag, and no raw-earnings flag outside a complete direct-QC envelope, fewer maximum feasible lifetime QCs than the lowest remaining recent-rule requirement proves establishment impossible before fully-route refusals or coverage enumeration. | B404.130(a) requires a recent rule "and you must be fully insured". The flag table's fully-route rules cannot change the independent recent-credit requirement. B404.130(b) needs 20 QCs; (c)–(d) permit the special half-elapsed-quarter rule with six-QC floor and 20-QC ceiling; RS .480 A also needs 20. At the earliest candidate start, remove every prior-period quarter from special elapsed time, including credited endpoints. Every actual use/disregard witness has at least those elapsed quarters, and later starts cannot reduce them. Taking the smallest applicable requirement therefore cannot exceed any true route minimum. Ignoring the fully insured prerequisite and window availability only relaxes the bound. Blindness (B404.130(e)) needs only fully insured status, and UNKNOWN prior history could remove further quarters; both disable this numerical proof and I16's recent scan. The minimum remains ahead of every boundary enumeration, including the recent scan. | -| I16. With known prior history, no blindness, and no route adding credits outside the declared envelope, a fully-route flag cannot establish a current period unless some nonoverlapping candidate quarter meets a recent rule under maximum feasible credits or the automatic pre1956 alternate remains possible. | B404.130(a) requires one rule "and you must be fully insured"; (b) requires 20 QCs in 40 quarters; (c) and (d) supply the under31 and subsequent-special recent alternatives. C320(b)(2) permits the onset quarter or a later disabled quarter, and C321(a) selects the first qualifying quarter. The scan includes the onset and horizon quarters and skips every candidate within a supplied prior-period quarter using I13's same overlap predicate. It retains B404.130(f)'s favorable all-period use or disregard and annual assignment, and relaxes only the fully insured prerequisite. Upper credits bound every feasible filling; failure there therefore proves every lower filling lacks a recent witness. An open RS .480 route remains an independent possibility for a fully-route flag. A complexity refusal is not impossibility and preserves the flag's own named refusal. The scan tests no flag-specific condition. | +| I15. With known prior history, no blindness, no foreign credits, no credit-route flag, and no raw-earnings flag outside a complete direct-QC envelope, fewer maximum feasible lifetime QCs than the lowest remaining recent-rule requirement proves establishment impossible before fully-route refusals or coverage enumeration. | B404.130(a) requires a recent rule "and you must be fully insured". The flag table's fully-route rules cannot change the independent recent-credit requirement. B404.130(b) needs 20 QCs; (c)–(d) permit the special half-elapsed-quarter rule with six-QC floor and 20-QC ceiling; RS .480 A also needs 20. At the earliest candidate start, remove every prior-period quarter from special elapsed time, including credited endpoints. Every actual use/disregard witness has at least those elapsed quarters, and later starts cannot reduce them. Taking the smallest applicable requirement therefore cannot exceed any true route minimum. Ignoring the fully insured prerequisite and window availability only relaxes the bound. Blindness (B404.130(e)) needs only fully insured status, and UNKNOWN prior history could remove further quarters; both disable this stronger numerical proof and I16's recent scan, but UNKNOWN prior history does not disable I17's six-QC horizon floor. The minimum remains ahead of every boundary enumeration, including the recent scan. | +| I16. With known prior history, no blindness, and no route adding credits outside the declared envelope, a fully-route flag cannot establish a current period unless some nonoverlapping candidate quarter meets a recent rule under maximum feasible credits or the automatic pre1956 alternate remains possible. | B404.130(a) requires one rule "and you must be fully insured"; (b) requires 20 QCs in 40 quarters; (c) and (d) supply the under31 and subsequent-special recent alternatives. C320(b)(2) permits the onset quarter or a later disabled quarter, and C321(a) selects the first qualifying quarter. The scan includes onset and horizon. For each complete annual placement and fixed prior treatment, its first insured quarter must clear I13's overlap predicate. A later clear quarter cannot repair an earlier insured overlap. With UNKNOWN earnings, lower fillings are included; at most 4,096 placements/fillings are enumerated. When every candidate is already clear, the existing upper-credit scan suffices. It retains B404.130(f)'s favorable all-period use or disregard and annual assignment, and relaxes only the fully insured prerequisite. Upper credits bound the recent test when no start can overlap. In the overlap corner, complete placements and unresolved lower fillings are tested together, because removing or moving an early QC can delay the first insured start. An open RS .480 route remains an independent possibility for a fully-route flag. A complexity refusal is not impossibility and preserves the flag's own named refusal. The scan tests no flag-specific condition. | +| I17. Every declared-envelope nonblind establishment route has at least six QCs feasible by its immutable start horizon, including fully-route flags and UNKNOWN prior histories. Blindness without a fully-route flag retains the ordinary fully insured floor. | B404.130(b)(2) requires "at least 20 QCs"; (c)(3)(ii) and (d)(2)(ii) require "at least 6 QCs in the 12-quarter period". Paragraph (f) changes the counted window, never this floor. Only (e) removes the recent requirement, retaining fully insured status. RS .480 A also needs twenty QCs by its start. UNKNOWN prior history may remove elapsed quarters or open a subsequent-special route, but cannot remove this minimum. Credits after the horizon cannot satisfy it. Foreign and unmodeled credit routes remain outside the declared envelope and precede the proof. | +| I18. An established pre1956 alternate uses one start quarter satisfying prior-period nonoverlap, the immutable horizon and the historical date limit together. | C320(b)(2), C321(a), I13 and RS .480 B.1 require an eligible insured start no later than 12/31/55. A later nonoverlapping ordinary candidate cannot validate an overlapping alternate candidate. This check does not change the alternate continuous clock, credited endpoint treatment, lower-credit exclusion scan, or false/UNKNOWN establishment. | | ID and UNKNOWN collapse | Captured text and alternative-route defense | | --- | --- | | U1. UNKNOWN prior history can collapse to empty solely for impossibility validation when no earliest prior period could start insured, on/after birth, before current onset and the FRA end. | C320(b)(2) and C321(a) require an insured beginning without a still-earlier period. A216(i)(2)(A) permits "five full calendar months' duration or" DIB entitlement "for one or more months". The scan therefore admits a one-month period and maximum feasible earnings. Any possible ordinary or specialist starting route stops the proof. It establishes no observed empty-history fact. | | U2. UNKNOWN current establishment needs no new-period alternative if there is no medical onset or onset is at/after the statutory latest starting month. | A216(i)(2)(A)-(D) and C321 prohibit a period without disability or a nonempty pre-FRA interval. This removes an impossible new-period alternative only; it does not remove UNKNOWN prior history or an existing period's UNKNOWN administrative end. | | U3. With unknown prior/current periods, true ordinary FULLY and CURRENTLY status under favorable all-period disregard decides true. A DISABILITY witness must also survive any current-establishment completion that ends the disability before that witness. | C320(a): "If benefits ... would be denied or reduced because of a period of disability, the period of disability will not be taken into consideration." B404.130(f) also permits counting all prior quarters if favorable. RS .120 requires all periods used or all disregarded; selective exclusions are not assumed. Specialist credit regimes are refused first. | -| U4. With unknown periods, fewer than six maximum feasible QCs decides false only on the ordinary route after specialist possibilities are excluded; it supplies no foreign-credit impossibility proof. | B404.110(b)(1) and B404.130(a) supply the ordinary six-QC prerequisite. U3's disregard cannot manufacture credits. UNKNOWN prior history disables both I15 and I16 and preserves a fully-route flag's named refusal even when every known recent window is empty. Foreign credits, credit-route flags, and raw-earnings flags outside a complete direct envelope also preserve named refusals. Without a fully-route flag, the direct-envelope contract and declared pre1956 alternate still obey I9; that alternate flag adds no route beyond B4. Blindness alone supplies no credits and does not replace the ordinary fully insured prerequisite. | +| U4. With unknown periods, fewer than six maximum QCs feasible by the immutable horizon proves establishment impossible after routes adding undeclared credits are excluded, except for blindness with a fully-route flag; it supplies no foreign-credit impossibility proof. | B404.110(b)(1) and B404.130(a) supply the ordinary six-QC prerequisite. U3's disregard cannot manufacture credits. UNKNOWN prior history disables both I15 and I16; it can preserve a fully-route refusal with empty recent windows only after the universal six-QC horizon floor clears (I17). Foreign credits, credit-route flags, and raw-earnings flags outside a complete direct envelope also preserve named refusals. The direct-envelope contract and declared pre1956 alternate still obey I9; that alternate flag adds no route beyond B4. Blindness alone supplies no credits and does not replace the ordinary fully insured prerequisite. | | U5. UNKNOWN earnings decide a requested Boolean only if all lower/upper ordinary earnings witnesses agree, under the permitted fixed-period/all-period treatments; an uncertain established start refuses only after at least one feasible filling survives. | B404.143 credits one QC for each increment, maximum four; B404.130 and .146 supply assignment/exclusion rules. Adding ordinary QCs cannot invalidate a fixed treatment. A derived start cannot be silently held fixed when the completion changes it. If a lower or upper representative cannot construct the declared period, but another single filling meets its end, continuity, and prior-overlap constraints, the public result is `unknown_earnings_years_decide_status`. If no ordinary filling can qualify by the declared end and all independent routes are impossible, it is an input error and creates no row. A deferred raw-conversion row uses temporary unknown fillings only for possibility, then retains its conversion refusal. Specialist possibilities and administrative-end candidates are considered separately. | | U6. UNKNOWN administrative end decides a status only when every end-quarter candidate from start through query/cap, plus permitted continuation, agrees, after applying any continuity lower bound. | A216(i)(2)(D) uses "whichever ... is the earlier"; C321(c)(3) includes "the last month for which you received benefits" after substantial gainful activity. Medical continuity cannot exclude early ends; a dated administrative continuity observation can. FRA/death caps limit the latest candidate and do not turn the unknown into a fact. Both ending and prior-history unknown facts remain disclosed when both are missing; UNKNOWN prior history uses the universal envelopes rather than inventing a derived current period to enumerate. The unchanged completion enumeration can include early endings rejected by I14 if declared concretely. Agreement across that larger set still implies agreement across every valid completion, while disagreement can preserve an extra refusal. An actual supplied end keeps its declared-date semantics; known ending provenance requires an ending date. | | U7. UNKNOWN SSPA applicability preserves an ordinary QC-only false status, but never a QC-only true status. | RS .102 B.2 says the worker "must meet one of the following additional requirements" and may fail "even if" the QC requirement is met. Applicability can remove ordinary insurance and cannot supply missing QCs. Known applicability retains adjudication refusal; any separate specialist path is refused first. | @@ -1081,7 +1098,7 @@ denominators: | Adding foreign credits to a declaration clearing fixed chronology always preserves the totalization refusal, one row, and exact weight, independently of its own-QC count or flags. Fixed overlap still produces an input error and no row. | `test_foreign_credit_refusal_is_independent_of_own_qc_count` (Hypothesis); `test_foreign_credits_refuse_without_an_own_qc_floor`; `test_fixed_overlap_precedes_every_flag_and_foreign_route` | | With known prior history and no blindness, any flag set supplying no additional credit under the complete direct-envelope contract leaves a total-QC shortfall below the recent-rule minimum input-invalid. The expected minimum is computed independently of `_minimum_current_period_qcs`; round 12 supplements this numerical proof with the candidate-quarter scan below. | `test_no_credit_flag_set_cannot_hide_independently_proved_shortfall` (Hypothesis); `test_no_credit_flag_shortfall_and_exact_minimum_pair`; `test_review_recent_credit_shortfall_cannot_be_cured_by_deeming` | | A flag cannot turn a declaration meeting every ordinary requirement into an input error. At the exact ordinary or under31 minimum, each flag retains its own reason, one row, and exact weight. | `test_no_flag_rejects_declaration_meeting_every_requirement` (Hypothesis); `test_no_credit_flag_shortfall_and_exact_minimum_pair`; `test_credit_route_keeps_refusal_even_with_complete_direct_envelope` | -| Fully-route flags retain their named refusals with blindness below six actual QCs or UNKNOWN prior history. The declared pre1956 alternate cannot bypass the ordinary six-QC floor even with blindness, but at 20 QCs retains its refusal. | `test_fully_route_refuses_when_recent_credit_proof_does_not_apply`; `test_pre1956_flag_with_blindness_keeps_ordinary_six_qc_floor` | +| Fully-route flags retain their named refusals with blindness below six actual QCs, or with UNKNOWN prior history and at least six QCs feasible by the horizon, surviving the joint optimistic-clock proof. The declared pre1956 alternate cannot bypass the ordinary six-QC floor even with blindness, but at 20 QCs retains its refusal. | `test_fully_route_refuses_when_recent_credit_proof_does_not_apply`; `test_pre1956_flag_with_blindness_keeps_ordinary_six_qc_floor` | | A complete direct envelope bounds every raw-earnings flag, including UNKNOWN rows; a raw row preserves its unmodeled allocation route. Military and Medicare government credits preserve a separate route even with direct rows. Combining flags preserves each independent route. | `test_raw_earnings_flag_preserves_route_only_without_direct_envelope`; `test_exact_classification_bounds_flags_that_add_no_declared_credit`; `test_credit_route_keeps_refusal_even_with_complete_direct_envelope`; `test_two_flag_classes_preserve_each_independent_route` | Round 12 closes round 11's temporal limitation. An invented worker born @@ -1111,7 +1128,7 @@ C321(a), and RS .480 A–B.1, not adjudications of the flags' own conditions. | At every tested quarter, a true ordinary DISABILITY witness stays true when only the fully insured prerequisite is relaxed on identical credits. | `test_witness_keyword_only_relaxes_fully_prerequisite` (Hypothesis) | | The recent scan includes both the onset quarter and horizon quarter, and the horizon quarter counts even when the end falls inside it. It does not admit a witness beyond an inferred recovery bound. A credit one quarter too old cannot enter any candidate window. | `test_scan_includes_onset_and_the_earliest_quarter_of_forty`; `test_scan_includes_horizon_quarter_and_stops_at_recovery_bound`; `test_scan_reaches_last_candidate_quarter_even_with_end_inside_quarter` | | The recent scan retains under-31 and subsequent-special requirements, favorable use of every prior period or disregard of every period, credited endpoints, and the shared rejection of candidate quarters inside supplied prior periods. | `test_special_recent_requirement_and_one_short`; `test_subsequent_special_recent_rule_can_pass_below_twenty_qcs`; `test_recent_window_uses_all_prior_periods_or_disregards_all`; `test_candidate_inside_prior_period_does_not_supply_recent_witness` | -| Blindness and UNKNOWN prior history preserve fully-route refusals even with empty recent windows. UNKNOWN recent years preserve possibility whenever an admissible filling supplies a recent witness, and every surviving concrete filling retains the flag's refusal. Complexity preserves that flag reason rather than substituting a computational refusal. | `test_empty_windows_keep_fully_route_blindness_and_unknown_prior_bypasses`; `test_unknown_recent_years_and_every_surviving_filling_keep_flag_reason`; `test_complexity_preserves_fully_route_reason` | +| Blindness and UNKNOWN prior history preserve fully-route refusals even with empty recent windows; UNKNOWN priors still require six horizon-feasible QCs and must survive the joint optimistic-clock proof. UNKNOWN recent years preserve possibility whenever an admissible filling supplies a recent witness, and every surviving concrete filling retains the flag's refusal. Complexity preserves that flag reason rather than substituting a computational refusal. | `test_empty_windows_keep_fully_route_blindness_and_unknown_prior_bypasses`; `test_unknown_recent_years_and_every_surviving_filling_keep_flag_reason`; `test_complexity_preserves_fully_route_reason` | | A declared pre1956 flag adds no establishment route beyond the automatic alternate: onset after 1955 with no ordinary route is invalid; either an ordinary witness or the historical alternate retains the named refusal. Credit-route and unbounded raw-earnings flags remain capable of adding credits, and a deferred conversion keeps its original reason when a recent witness remains possible. Surviving outcomes retain one evaluator row and exact weight 11/5. | `test_pre1956_flag_cannot_open_a_route_after_1955`; `test_pre1956_flag_keeps_named_refusal_when_alternate_conditions_hold`; `test_pre1956_flag_keeps_named_refusal_when_ordinary_route_is_open`; `test_credit_and_unbounded_raw_earnings_flags_can_add_recent_credits`; `test_deferred_conversion_keeps_original_refusal_with_possible_recent_rule` | The round-8 UNKNOWN-ending and round-9 UNKNOWN-establishment completion @@ -1611,6 +1628,118 @@ conditions; an explicitly declared fully insured route remains a supplied fact even if its cohort would not satisfy 404.112. These corrections make no payment adjudication and establish no dollar change. +## Round 13 joint classification audit + +Sections 404.130(b)–(d) and (f) leave the recent floor intact when prior +history is UNKNOWN; paragraph (e) removes the recent requirement only for +blindness. RS .480 A separately requires twenty credits. The horizon +floor therefore runs after the stronger known-history numerical proof and +before UNKNOWN-prior, recent and alternate possibilities. Foreign credits +and routes adding credits outside the declared envelope still precede it. + +The independent oracle found further instances of the same uncoupled +witness class. A prior period being possible does not show that any one +completion also insures the current period. With UNKNOWN priors, a new +necessary-condition proof permits historical blindness at the first +possible fully insured quarter, then deletes every later uncredited +quarter before the current candidate while retaining every QC, even +credits that a real freeze interior would remove. This clock is more +favorable than any real chain of prior periods. Restoring a QC adds at +most one elapsed quarter while adding one credit, so neither a half-clock +nor a 20/40 test becomes harder. All upper annual placements therefore +bound every lower filling. The proof also requires six credits before age +31 for any possible subsequent-special prior. It rejects only if every +relaxed placement fails. More than 4,096 placements leaves the history +unresolved. It does not construct a history or change the earlier +`_minimum_current_period_qcs` proof. This additional joint proof applies +to current onsets from 1956; earlier UNKNOWN current onsets keep the +existing conservative alternate/history machinery and are outside the +added UNKNOWN-history oracle lattice. + +For known priors, 404.321(a) fixes onset when insured then, otherwise the +first insured quarter. A fully-route flag presumes that prerequisite and +changes nothing else. The recent scan now holds one complete annual +placement and prior treatment fixed before selecting that first quarter; +a later clear quarter cannot repair an overlapping first quarter. A blind +fully-route declaration is insured at onset and needs a clear onset +quarter. The ordinary constructor also tries bounded annual placements +and fixed prior treatments when its initially favorable onset assignment +overlaps a prior. This preserves the valid converse: moving one annual QC +from Q1 to Q2 can make Q2 the first insured, nonoverlapping start. Both the +possibility proof and the public constructor use that same construction. +The resolved annual filling and prior treatment also supply the public +DISABILITY witness, so its qualifying quarter agrees with that legal +first start rather than reverting to a new favorable onset assignment. +The historical alternate has its own eligible date candidates and retains +its existing continuous clock and lower-credit exclusion. + +| Invariant | Executed tests | +| --- | --- | +| Nonblind declared-envelope routes need six credits by the immutable horizon, including UNKNOWN prior history and every fully route; later credits cannot repair a shortfall. | `test_unknown_prior_fully_route_floor_uses_horizon_credits`; `test_twenty_future_credits_cannot_repair_zero_by_start_horizon`; `test_classification_oracle_hypothesis`; `test_classification_oracle_unknown_years_straddle_start_horizon` | +| Blind fully routes without prior overlap preserve their zero-credit named refusal; foreign and credit-adding routes precede the floor. | `test_blind_fully_route_with_zero_credits_keeps_named_refusal`; `test_foreign_and_credit_adding_routes_precede_floor`; `test_classification_oracle_modern_lattice` | +| One alternate start clears overlap, horizon and the 1955 limit together; credited endpoints and false/UNKNOWN establishment retain their treatment. | `test_review_alternate_start_must_clear_same_prior_overlap`; `test_alternate_uses_one_clear_candidate_after_prior_ending_quarter`; `test_unestablished_alternate_keeps_prior_treatment`; `test_classification_oracle_historical_boundary_lattice` | +| UNKNOWN priors cannot supply a special route without six credits before age 31, or couple incompatible earliest-prior and current windows. | `test_classification_oracle_unknown_prior_cannot_invent_special_eligibility`; `test_classification_oracle_unknown_prior_must_jointly_insure_current`; `test_classification_oracle_unknown_twenty_qcs_need_one_joint_start`; generated `test_classification_oracle_hypothesis` | +| Each known-prior filling and treatment has one first insured start. Annual flexibility can delay that start, but an already insured overlapping onset cannot be repaired by a later candidate. | `test_classification_oracle_fully_flag_cannot_delay_an_insured_onset`; `test_classification_oracle_blind_fully_flag_still_has_one_first_start`; `test_classification_oracle_annual_placement_can_delay_first_insured_quarter`; `test_classification_oracle_annual_placement_boundary_lattice`; `test_disability_witness_uses_the_legal_annual_start_filling` | +| Invalid declarations have zero rows and weight; each valid computed or named-refusal outcome has exactly one row and its full rational weight. | Every new regression and lattice evaluation; `test_classification_oracle_hypothesis` | + +### Independent oracle and bounds + +`tests/test_track_b_insured_status_classification_oracle.py` uses public +input/evaluator types and plain arithmetic. It calls no private rule +helper. Its 4,819 deterministic declarations and 48 generated examples +plus an explicit example vary modern ages 24, 29, 42 and 60; historical +births 1890, 1900 and 1910; onset and end quarters around 1952–1956; +recovery, continuity, death and exit bounds; none, one, two, special and +UNKNOWN priors; blindness; all four fully routes, the alternate and flag +pairs; credits 0, 5, 6, 19, 20 and 24 in old, recent and boundary placements; +and UNKNOWN credit years before and after the start horizon. Four focused +controls also cover adjacent age-31 quarters and 1952Q2/Q3 start horizons. + +For every selected declaration it enumerates annual placements, every +UNKNOWN-year subset, start quarters, fixed all-use/all-disregard prior +treatments retaining credited endpoints, and UNKNOWN month endings through +query plus the FRA/death continuation cap. At most two observed annual +totals are partial and two years UNKNOWN; the largest selected placement +space is 192. UNKNOWN history includes every empty/one-period quarter +interval in its stated range, with exact endings before onset, plus a +bounded two-period class consisting of a blind fully-route prefix and +subsequent special period. A prior start must itself be insured. This +preserves the defensible historical-blindness completion even when current +blindness is false. The oracle does not exhaust arbitrary two-period or +three-or-more UNKNOWN histories, alternate-founded UNKNOWN prior starts, +raw earnings, credit-adding flags, foreign routes, administrative filing +facts or SSPA211. Negative UNKNOWN examples have separate impossibility +proofs that also exclude extra periods. Classification is the tested +principle; returned DLI and per-test diagnostic assignment coherence are +outside this oracle's claim. + +### Executed counterexamples and corrected oracle assumptions + +The original zero-credit UNKNOWN-prior finding and the prior ending in +1955Q4 both now raise input errors. The independent audit additionally +found a young no-flag six-credit prefix requiring seven current credits; +an over-31 fully-route case with no six credits before 31; a twenty-credit +record whose earliest prior and current 40-quarter windows cannot share +the oldest credit; fully-route first-onset overlaps, including blindness; +and a valid annual Q2 placement rejected by a greedy Q1 assignment. Each +has a named regression in the oracle file. Their exact invented dates, +credits, first failures and dispositions are retained in the round-13 +report. These corrections change classification and denominator inclusion, +not a computed payment. + +Two oracle assumptions were corrected: it initially permitted a later +ordinary start after an insured overlapping onset, contrary to 404.321(a), +and it initially omitted a past-blindness prefix from UNKNOWN histories. +The corrected oracle fixes the first insured quarter within each filling +and permits that historical blindness completion. No unexplained or +silently accepted disagreement is intended. + +The round-11 four fully-route assertions for six credits first earned +after age 31 are retained unchanged as the dispatch explicitly requires. +The joint proof exposes their incompatibility with 404.130(d)'s special +prior premise. Any resulting failures are reported individually; those +assertions are not weakened or relabeled as passing. + Mutation checks are recorded in [`track_b_insured_status_mutations.json`](track_b_insured_status_mutations.json). Every recorded implementation mutation was caught and reverted. diff --git a/docs/design/track_b_insured_status_mutations.json b/docs/design/track_b_insured_status_mutations.json index b6bdd25cd..a3897b966 100644 --- a/docs/design/track_b_insured_status_mutations.json +++ b/docs/design/track_b_insured_status_mutations.json @@ -3840,5 +3840,532 @@ } ], "round_12_note": "Ten deliberate isolated in-memory mutations were caught and discarded. All four new generated properties bite, including both recent-rule exactness properties, the alternate oracle, and strict relaxation. Every mutation run audited zero restricted opens or spawned processes and verified original implementation bytes unchanged. Standalone reproduction commands include their own audit hook and exact source pin.", - "round_12_final_source_sha256": "8ef822d784136ae3b821cb75ec270e945d1972d5cfa10f4ae533fd65f6c0f018" + "round_12_final_source_sha256": "8ef822d784136ae3b821cb75ec270e945d1972d5cfa10f4ae533fd65f6c0f018", + "round_13_mutations": [ + { + "name": "unknown_bypass_above_floor", + "source_sha256": "1234c1cf5f199b92a102d71ad3c41f7a177ca242df626a97eaf6b4e9b889771d", + "changes": [ + { + "before": " if fully_route and person.statutory_blindness:\n return _outside_prior_periods(person, _qid(person.disability_onset))\n", + "after": " if fully_route and (\n person.statutory_blindness\n or person.prior_disability_periods_provenance\n is EarningsProvenance.UNKNOWN\n ):\n return _outside_prior_periods(person, _qid(person.disability_onset))\n" + } + ], + "spec_path": "scratch/review/round13-mutation-unknown_bypass_above_floor.json", + "node": "tests/test_track_b_insured_status_fix_round_13.py::test_review_unknown_prior_cannot_remove_six_qc_floor", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round13 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round13 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND13_MUTATION=scratch/review/round13-mutation-unknown_bypass_above_floor.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round13_named.py -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_insured_status_fix_round_13.py::test_review_unknown_prior_cannot_remove_six_qc_floor > scratch/review/round13-mutation-unknown_bypass_above_floor.log 2>&1", + "log": "scratch/review/round13-mutation-unknown_bypass_above_floor.log", + "audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_13.py::test_review_unknown_prior_cannot_remove_six_qc_floor[None]", + "tests/test_track_b_insured_status_fix_round_13.py::test_review_unknown_prior_cannot_remove_six_qc_floor[coverage_end1]" + ], + "failed": 2, + "pytest_summary": "2 failed in 1.76s", + "passed": 0, + "runtime_seconds": 1.76, + "exit_code": 1, + "killed": true, + "source_restored": true, + "restoration": "Runner execs mutation in module namespace only and asserts source bytes unchanged before printing OPEN_AUDIT." + }, + { + "name": "lifetime_qcs_in_floor", + "source_sha256": "1234c1cf5f199b92a102d71ad3c41f7a177ca242df626a97eaf6b4e9b889771d", + "changes": [ + { + "before": " if horizon_qcs < 6:\n", + "after": " if maximum_qcs < 6:\n" + } + ], + "spec_path": "scratch/review/round13-mutation-lifetime_qcs_in_floor.json", + "node": "tests/test_track_b_insured_status_fix_round_13.py::test_twenty_future_credits_cannot_repair_zero_by_start_horizon", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round13 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round13 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND13_MUTATION=scratch/review/round13-mutation-lifetime_qcs_in_floor.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round13_named.py -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_insured_status_fix_round_13.py::test_twenty_future_credits_cannot_repair_zero_by_start_horizon > scratch/review/round13-mutation-lifetime_qcs_in_floor.log 2>&1", + "log": "scratch/review/round13-mutation-lifetime_qcs_in_floor.log", + "audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_13.py::test_twenty_future_credits_cannot_repair_zero_by_start_horizon[CoverageCondition.DEEMED_FULLY_INSURED]", + "tests/test_track_b_insured_status_fix_round_13.py::test_twenty_future_credits_cannot_repair_zero_by_start_horizon[CoverageCondition.TRANSITIONAL_INSURED]", + "tests/test_track_b_insured_status_fix_round_13.py::test_twenty_future_credits_cannot_repair_zero_by_start_horizon[CoverageCondition.EARNED_BASIS]", + "tests/test_track_b_insured_status_fix_round_13.py::test_twenty_future_credits_cannot_repair_zero_by_start_horizon[CoverageCondition.SIMPLIFIED_PRE1951]" + ], + "failed": 4, + "pytest_summary": "4 failed in 2.07s", + "passed": 0, + "runtime_seconds": 2.07, + "exit_code": 1, + "killed": true, + "source_restored": true, + "restoration": "Runner execs mutation in module namespace only and asserts source bytes unchanged before printing OPEN_AUDIT." + }, + { + "name": "blindness_after_floor", + "source_sha256": "1234c1cf5f199b92a102d71ad3c41f7a177ca242df626a97eaf6b4e9b889771d", + "changes": [ + { + "before": " if fully_route and person.statutory_blindness:\n return _outside_prior_periods(person, _qid(person.disability_onset))\n", + "after": " if False and fully_route and person.statutory_blindness:\n return _outside_prior_periods(person, _qid(person.disability_onset))\n" + } + ], + "spec_path": "scratch/review/round13-mutation-blindness_after_floor.json", + "node": "tests/test_track_b_insured_status_fix_round_13.py::test_blind_fully_route_with_zero_credits_keeps_named_refusal", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round13 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round13 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND13_MUTATION=scratch/review/round13-mutation-blindness_after_floor.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round13_named.py -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_insured_status_fix_round_13.py::test_blind_fully_route_with_zero_credits_keeps_named_refusal > scratch/review/round13-mutation-blindness_after_floor.log 2>&1", + "log": "scratch/review/round13-mutation-blindness_after_floor.log", + "audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_13.py::test_blind_fully_route_with_zero_credits_keeps_named_refusal[CoverageCondition.DEEMED_FULLY_INSURED]", + "tests/test_track_b_insured_status_fix_round_13.py::test_blind_fully_route_with_zero_credits_keeps_named_refusal[CoverageCondition.TRANSITIONAL_INSURED]", + "tests/test_track_b_insured_status_fix_round_13.py::test_blind_fully_route_with_zero_credits_keeps_named_refusal[CoverageCondition.EARNED_BASIS]", + "tests/test_track_b_insured_status_fix_round_13.py::test_blind_fully_route_with_zero_credits_keeps_named_refusal[CoverageCondition.SIMPLIFIED_PRE1951]" + ], + "failed": 4, + "pytest_summary": "4 failed in 5.46s", + "passed": 0, + "runtime_seconds": 5.46, + "exit_code": 1, + "killed": true, + "source_restored": true, + "restoration": "Runner execs mutation in module namespace only and asserts source bytes unchanged before printing OPEN_AUDIT." + }, + { + "name": "floor_applies_to_credit_routes", + "source_sha256": "1234c1cf5f199b92a102d71ad3c41f7a177ca242df626a97eaf6b4e9b889771d", + "changes": [ + { + "before": " if _flagged_establishment_possible(person, years):\n return True\n", + "after": " if _flagged_establishment_possible(person, years):\n rows, _ = _world(person, credits, _qid(horizon), exit_month, False)\n return sum(len(_assign_qcs(*row)) for row in rows.values()) >= 6\n" + } + ], + "spec_path": "scratch/review/round13-mutation-floor_applies_to_credit_routes.json", + "node": "tests/test_track_b_insured_status_fix_round_13.py::test_foreign_and_credit_adding_routes_precede_floor", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round13 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round13 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND13_MUTATION=scratch/review/round13-mutation-floor_applies_to_credit_routes.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round13_named.py -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_insured_status_fix_round_13.py::test_foreign_and_credit_adding_routes_precede_floor > scratch/review/round13-mutation-floor_applies_to_credit_routes.log 2>&1", + "log": "scratch/review/round13-mutation-floor_applies_to_credit_routes.log", + "audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_13.py::test_foreign_and_credit_adding_routes_precede_floor[CoverageCondition.MILITARY_CREDITS]", + "tests/test_track_b_insured_status_fix_round_13.py::test_foreign_and_credit_adding_routes_precede_floor[CoverageCondition.MEDICARE_GOVERNMENT_EMPLOYMENT]", + "tests/test_track_b_insured_status_fix_round_13.py::test_foreign_and_credit_adding_routes_precede_floor[CoverageCondition.RAILROAD_CREDITS]", + "tests/test_track_b_insured_status_fix_round_13.py::test_foreign_and_credit_adding_routes_precede_floor[CoverageCondition.FISCAL_TAXABLE_YEAR]", + "tests/test_track_b_insured_status_fix_round_13.py::test_foreign_and_credit_adding_routes_precede_floor[CoverageCondition.SHORT_TAXABLE_YEAR]" + ], + "failed": 5, + "pytest_summary": "5 failed, 1 passed in 6.77s", + "passed": 1, + "runtime_seconds": 6.77, + "exit_code": 1, + "killed": true, + "source_restored": true, + "restoration": "Runner execs mutation in module namespace only and asserts source bytes unchanged before printing OPEN_AUDIT." + }, + { + "name": "floor_at_five", + "source_sha256": "1234c1cf5f199b92a102d71ad3c41f7a177ca242df626a97eaf6b4e9b889771d", + "changes": [ + { + "before": " if horizon_qcs < 6:\n", + "after": " if horizon_qcs < 5:\n" + } + ], + "spec_path": "scratch/review/round13-mutation-floor_at_five.json", + "node": "tests/test_track_b_insured_status_fix_round_13.py::test_unknown_prior_fully_route_floor_uses_horizon_credits", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round13 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round13 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND13_MUTATION=scratch/review/round13-mutation-floor_at_five.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round13_named.py -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_insured_status_fix_round_13.py::test_unknown_prior_fully_route_floor_uses_horizon_credits > scratch/review/round13-mutation-floor_at_five.log 2>&1", + "log": "scratch/review/round13-mutation-floor_at_five.log", + "audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_13.py::test_unknown_prior_fully_route_floor_uses_horizon_credits[five-CoverageCondition.DEEMED_FULLY_INSURED]", + "tests/test_track_b_insured_status_fix_round_13.py::test_unknown_prior_fully_route_floor_uses_horizon_credits[five-CoverageCondition.TRANSITIONAL_INSURED]", + "tests/test_track_b_insured_status_fix_round_13.py::test_unknown_prior_fully_route_floor_uses_horizon_credits[five-CoverageCondition.EARNED_BASIS]", + "tests/test_track_b_insured_status_fix_round_13.py::test_unknown_prior_fully_route_floor_uses_horizon_credits[five-CoverageCondition.SIMPLIFIED_PRE1951]", + "tests/test_track_b_insured_status_fix_round_13.py::test_unknown_prior_fully_route_floor_uses_horizon_credits[sixth-one-quarter-late-CoverageCondition.DEEMED_FULLY_INSURED]", + "tests/test_track_b_insured_status_fix_round_13.py::test_unknown_prior_fully_route_floor_uses_horizon_credits[sixth-one-quarter-late-CoverageCondition.TRANSITIONAL_INSURED]", + "tests/test_track_b_insured_status_fix_round_13.py::test_unknown_prior_fully_route_floor_uses_horizon_credits[sixth-one-quarter-late-CoverageCondition.EARNED_BASIS]", + "tests/test_track_b_insured_status_fix_round_13.py::test_unknown_prior_fully_route_floor_uses_horizon_credits[sixth-one-quarter-late-CoverageCondition.SIMPLIFIED_PRE1951]" + ], + "failed": 8, + "pytest_summary": "8 failed, 4 passed in 4.69s", + "passed": 4, + "runtime_seconds": 4.69, + "exit_code": 1, + "killed": true, + "source_restored": true, + "restoration": "Runner execs mutation in module namespace only and asserts source bytes unchanged before printing OPEN_AUDIT." + }, + { + "name": "floor_at_seven", + "source_sha256": "1234c1cf5f199b92a102d71ad3c41f7a177ca242df626a97eaf6b4e9b889771d", + "changes": [ + { + "before": " if horizon_qcs < 6:\n", + "after": " if horizon_qcs < 7:\n" + } + ], + "spec_path": "scratch/review/round13-mutation-floor_at_seven.json", + "node": "tests/test_track_b_insured_status_fix_round_13.py::test_unknown_prior_fully_route_floor_uses_horizon_credits", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round13 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round13 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND13_MUTATION=scratch/review/round13-mutation-floor_at_seven.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round13_named.py -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_insured_status_fix_round_13.py::test_unknown_prior_fully_route_floor_uses_horizon_credits > scratch/review/round13-mutation-floor_at_seven.log 2>&1", + "log": "scratch/review/round13-mutation-floor_at_seven.log", + "audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_13.py::test_unknown_prior_fully_route_floor_uses_horizon_credits[six-CoverageCondition.DEEMED_FULLY_INSURED]", + "tests/test_track_b_insured_status_fix_round_13.py::test_unknown_prior_fully_route_floor_uses_horizon_credits[six-CoverageCondition.TRANSITIONAL_INSURED]", + "tests/test_track_b_insured_status_fix_round_13.py::test_unknown_prior_fully_route_floor_uses_horizon_credits[six-CoverageCondition.EARNED_BASIS]", + "tests/test_track_b_insured_status_fix_round_13.py::test_unknown_prior_fully_route_floor_uses_horizon_credits[six-CoverageCondition.SIMPLIFIED_PRE1951]" + ], + "failed": 4, + "pytest_summary": "4 failed, 8 passed in 5.74s", + "passed": 8, + "runtime_seconds": 5.74, + "exit_code": 1, + "killed": true, + "source_restored": true, + "restoration": "Runner execs mutation in module namespace only and asserts source bytes unchanged before printing OPEN_AUDIT." + }, + { + "name": "drop_alternate_overlap_skip", + "source_sha256": "1234c1cf5f199b92a102d71ad3c41f7a177ca242df626a97eaf6b4e9b889771d", + "changes": [ + { + "before": " if person.current_disability_period_established and not (\n _outside_prior_periods(person, quarter)\n ):\n continue\n", + "after": "" + } + ], + "spec_path": "scratch/review/round13-mutation-drop_alternate_overlap_skip.json", + "node": "tests/test_track_b_insured_status_fix_round_13.py::test_review_alternate_start_must_clear_same_prior_overlap", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round13 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round13 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND13_MUTATION=scratch/review/round13-mutation-drop_alternate_overlap_skip.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round13_named.py -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_insured_status_fix_round_13.py::test_review_alternate_start_must_clear_same_prior_overlap > scratch/review/round13-mutation-drop_alternate_overlap_skip.log 2>&1", + "log": "scratch/review/round13-mutation-drop_alternate_overlap_skip.log", + "audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_13.py::test_review_alternate_start_must_clear_same_prior_overlap[end0-None]", + "tests/test_track_b_insured_status_fix_round_13.py::test_review_alternate_start_must_clear_same_prior_overlap[end0-coverage_end1]", + "tests/test_track_b_insured_status_fix_round_13.py::test_review_alternate_start_must_clear_same_prior_overlap[end1-None]", + "tests/test_track_b_insured_status_fix_round_13.py::test_review_alternate_start_must_clear_same_prior_overlap[end1-coverage_end1]", + "tests/test_track_b_insured_status_fix_round_13.py::test_review_alternate_start_must_clear_same_prior_overlap[end2-None]", + "tests/test_track_b_insured_status_fix_round_13.py::test_review_alternate_start_must_clear_same_prior_overlap[end2-coverage_end1]" + ], + "failed": 6, + "pytest_summary": "6 failed in 4.31s", + "passed": 0, + "runtime_seconds": 4.31, + "exit_code": 1, + "killed": true, + "source_restored": true, + "restoration": "Runner execs mutation in module namespace only and asserts source bytes unchanged before printing OPEN_AUDIT." + }, + { + "name": "alternate_skip_unestablished", + "source_sha256": "1234c1cf5f199b92a102d71ad3c41f7a177ca242df626a97eaf6b4e9b889771d", + "changes": [ + { + "before": " if person.current_disability_period_established and not (\n _outside_prior_periods(person, quarter)\n ):\n continue\n", + "after": " if not _outside_prior_periods(person, quarter):\n continue\n" + } + ], + "spec_path": "scratch/review/round13-mutation-alternate_skip_unestablished.json", + "node": "tests/test_track_b_insured_status_fix_round_13.py::test_unestablished_alternate_keeps_prior_treatment", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round13 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round13 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND13_MUTATION=scratch/review/round13-mutation-alternate_skip_unestablished.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round13_named.py -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_insured_status_fix_round_13.py::test_unestablished_alternate_keeps_prior_treatment > scratch/review/round13-mutation-alternate_skip_unestablished.log 2>&1", + "log": "scratch/review/round13-mutation-alternate_skip_unestablished.log", + "audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_13.py::test_unestablished_alternate_keeps_prior_treatment[false]", + "tests/test_track_b_insured_status_fix_round_13.py::test_unestablished_alternate_keeps_prior_treatment[unknown]" + ], + "failed": 2, + "pytest_summary": "2 failed in 2.70s", + "passed": 0, + "runtime_seconds": 2.7, + "exit_code": 1, + "killed": true, + "source_restored": true, + "restoration": "Runner execs mutation in module namespace only and asserts source bytes unchanged before printing OPEN_AUDIT." + }, + { + "name": "alternate_skip_wrong_quarter", + "source_sha256": "1234c1cf5f199b92a102d71ad3c41f7a177ca242df626a97eaf6b4e9b889771d", + "changes": [ + { + "before": " if person.current_disability_period_established and not (\n _outside_prior_periods(person, quarter)\n ):\n continue\n", + "after": " if person.current_disability_period_established and not (\n _outside_prior_periods(person, _qid(person.disability_onset))\n ):\n continue\n" + } + ], + "spec_path": "scratch/review/round13-mutation-alternate_skip_wrong_quarter.json", + "node": "tests/test_track_b_insured_status_fix_round_13.py::test_alternate_uses_one_clear_candidate_after_prior_ending_quarter", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round13 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round13 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND13_MUTATION=scratch/review/round13-mutation-alternate_skip_wrong_quarter.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round13_named.py -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_insured_status_fix_round_13.py::test_alternate_uses_one_clear_candidate_after_prior_ending_quarter > scratch/review/round13-mutation-alternate_skip_wrong_quarter.log 2>&1", + "log": "scratch/review/round13-mutation-alternate_skip_wrong_quarter.log", + "audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_13.py::test_alternate_uses_one_clear_candidate_after_prior_ending_quarter[False]", + "tests/test_track_b_insured_status_fix_round_13.py::test_alternate_uses_one_clear_candidate_after_prior_ending_quarter[True]" + ], + "failed": 2, + "pytest_summary": "2 failed in 6.41s", + "passed": 0, + "runtime_seconds": 6.41, + "exit_code": 1, + "killed": true, + "source_restored": true, + "restoration": "Runner execs mutation in module namespace only and asserts source bytes unchanged before printing OPEN_AUDIT." + }, + { + "name": "oracle_ordinary_recent_route_removed", + "source_sha256": "1234c1cf5f199b92a102d71ad3c41f7a177ca242df626a97eaf6b4e9b889771d", + "changes": [ + { + "before": " if fully_route and _recent_rule_possible(\n person, credits, horizon, exit_month, lower_credits=lower_credits\n ):\n return True\n", + "after": " if False and fully_route and _recent_rule_possible(\n person, credits, horizon, exit_month, lower_credits=lower_credits\n ):\n return True\n" + } + ], + "spec_path": "scratch/review/round13-mutation-oracle_ordinary_recent_route_removed.json", + "node": "tests/test_track_b_insured_status_classification_oracle.py::test_classification_oracle_requires_ordinary_recent_route", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round13 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round13 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND13_MUTATION=scratch/review/round13-mutation-oracle_ordinary_recent_route_removed.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round13_named.py -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_insured_status_classification_oracle.py::test_classification_oracle_requires_ordinary_recent_route > scratch/review/round13-mutation-oracle_ordinary_recent_route_removed.log 2>&1", + "log": "scratch/review/round13-mutation-oracle_ordinary_recent_route_removed.log", + "audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_classification_oracle.py::test_classification_oracle_requires_ordinary_recent_route" + ], + "failed": 1, + "pytest_summary": "1 failed in 5.56s", + "passed": 0, + "runtime_seconds": 5.56, + "exit_code": 1, + "killed": true, + "source_restored": true, + "restoration": "Runner execs mutation in module namespace only and asserts source bytes unchanged before printing OPEN_AUDIT.", + "oracle_test_sha256": "4ff36ba10c71ac077ec7a678353e420454e11bcb2f53b8b21816e4315d74b5f5" + }, + { + "name": "oracle_alternate_route_removed", + "source_sha256": "1234c1cf5f199b92a102d71ad3c41f7a177ca242df626a97eaf6b4e9b889771d", + "changes": [ + { + "before": " if _pre1956_alternate_possible(\n person, credits, month, exit_month, lower_credits=lower_credits\n ):\n return True\n", + "after": " if False and _pre1956_alternate_possible(\n person, credits, month, exit_month, lower_credits=lower_credits\n ):\n return True\n" + } + ], + "spec_path": "scratch/review/round13-mutation-oracle_alternate_route_removed.json", + "node": "tests/test_track_b_insured_status_classification_oracle.py::test_classification_oracle_requires_alternate_route", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round13 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round13 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND13_MUTATION=scratch/review/round13-mutation-oracle_alternate_route_removed.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round13_named.py -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_insured_status_classification_oracle.py::test_classification_oracle_requires_alternate_route > scratch/review/round13-mutation-oracle_alternate_route_removed.log 2>&1", + "log": "scratch/review/round13-mutation-oracle_alternate_route_removed.log", + "audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_classification_oracle.py::test_classification_oracle_requires_alternate_route" + ], + "failed": 1, + "pytest_summary": "1 failed in 5.01s", + "passed": 0, + "runtime_seconds": 5.01, + "exit_code": 1, + "killed": true, + "source_restored": true, + "restoration": "Runner execs mutation in module namespace only and asserts source bytes unchanged before printing OPEN_AUDIT.", + "oracle_test_sha256": "4ff36ba10c71ac077ec7a678353e420454e11bcb2f53b8b21816e4315d74b5f5" + }, + { + "name": "oracle_unknown_joint_proof_removed", + "source_sha256": "1234c1cf5f199b92a102d71ad3c41f7a177ca242df626a97eaf6b4e9b889771d", + "changes": [ + { + "before": " and _unknown_prior_joint_shortfall(person, rows, horizon, fully_route)\n", + "after": " and False and _unknown_prior_joint_shortfall(person, rows, horizon, fully_route)\n" + } + ], + "spec_path": "scratch/review/round13-mutation-oracle_unknown_joint_proof_removed.json", + "node": "tests/test_track_b_insured_status_classification_oracle.py::test_classification_oracle_unknown_prior_must_jointly_insure_current", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round13 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round13 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND13_MUTATION=scratch/review/round13-mutation-oracle_unknown_joint_proof_removed.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round13_named.py -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_insured_status_classification_oracle.py::test_classification_oracle_unknown_prior_must_jointly_insure_current > scratch/review/round13-mutation-oracle_unknown_joint_proof_removed.log 2>&1", + "log": "scratch/review/round13-mutation-oracle_unknown_joint_proof_removed.log", + "audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_classification_oracle.py::test_classification_oracle_unknown_prior_must_jointly_insure_current" + ], + "failed": 1, + "pytest_summary": "1 failed in 22.10s", + "passed": 0, + "runtime_seconds": 22.1, + "exit_code": 1, + "killed": true, + "source_restored": true, + "restoration": "Runner execs mutation in module namespace only and asserts source bytes unchanged before printing OPEN_AUDIT.", + "oracle_test_sha256": "4ff36ba10c71ac077ec7a678353e420454e11bcb2f53b8b21816e4315d74b5f5" + }, + { + "name": "oracle_first_insured_start_repair_removed", + "source_sha256": "1234c1cf5f199b92a102d71ad3c41f7a177ca242df626a97eaf6b4e9b889771d", + "changes": [ + { + "before": " if _outside_prior_periods(person, quarter):\n return True\n break\n", + "after": " if _outside_prior_periods(person, quarter):\n return True\n" + } + ], + "spec_path": "scratch/review/round13-mutation-oracle_first_insured_start_repair_removed.json", + "node": "tests/test_track_b_insured_status_classification_oracle.py::test_classification_oracle_fully_flag_cannot_delay_an_insured_onset", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round13 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round13 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND13_MUTATION=scratch/review/round13-mutation-oracle_first_insured_start_repair_removed.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round13_named.py -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_insured_status_classification_oracle.py::test_classification_oracle_fully_flag_cannot_delay_an_insured_onset > scratch/review/round13-mutation-oracle_first_insured_start_repair_removed.log 2>&1", + "log": "scratch/review/round13-mutation-oracle_first_insured_start_repair_removed.log", + "audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_classification_oracle.py::test_classification_oracle_fully_flag_cannot_delay_an_insured_onset[CoverageCondition.DEEMED_FULLY_INSURED]", + "tests/test_track_b_insured_status_classification_oracle.py::test_classification_oracle_fully_flag_cannot_delay_an_insured_onset[CoverageCondition.TRANSITIONAL_INSURED]", + "tests/test_track_b_insured_status_classification_oracle.py::test_classification_oracle_fully_flag_cannot_delay_an_insured_onset[CoverageCondition.EARNED_BASIS]", + "tests/test_track_b_insured_status_classification_oracle.py::test_classification_oracle_fully_flag_cannot_delay_an_insured_onset[CoverageCondition.SIMPLIFIED_PRE1951]" + ], + "failed": 4, + "pytest_summary": "4 failed in 4.71s", + "passed": 0, + "runtime_seconds": 4.71, + "exit_code": 1, + "killed": true, + "source_restored": true, + "restoration": "Runner execs mutation in module namespace only and asserts source bytes unchanged before printing OPEN_AUDIT.", + "oracle_test_sha256": "4ff36ba10c71ac077ec7a678353e420454e11bcb2f53b8b21816e4315d74b5f5" + }, + { + "name": "oracle_blind_first_start_overlap_removed", + "source_sha256": "1234c1cf5f199b92a102d71ad3c41f7a177ca242df626a97eaf6b4e9b889771d", + "changes": [ + { + "before": " if fully_route and person.statutory_blindness:\n return _outside_prior_periods(person, _qid(person.disability_onset))\n", + "after": " if fully_route and person.statutory_blindness:\n return True\n" + } + ], + "spec_path": "scratch/review/round13-mutation-oracle_blind_first_start_overlap_removed.json", + "node": "tests/test_track_b_insured_status_classification_oracle.py::test_classification_oracle_blind_fully_flag_still_has_one_first_start", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round13 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round13 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND13_MUTATION=scratch/review/round13-mutation-oracle_blind_first_start_overlap_removed.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round13_named.py -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_insured_status_classification_oracle.py::test_classification_oracle_blind_fully_flag_still_has_one_first_start > scratch/review/round13-mutation-oracle_blind_first_start_overlap_removed.log 2>&1", + "log": "scratch/review/round13-mutation-oracle_blind_first_start_overlap_removed.log", + "audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_classification_oracle.py::test_classification_oracle_blind_fully_flag_still_has_one_first_start[CoverageCondition.DEEMED_FULLY_INSURED]", + "tests/test_track_b_insured_status_classification_oracle.py::test_classification_oracle_blind_fully_flag_still_has_one_first_start[CoverageCondition.TRANSITIONAL_INSURED]", + "tests/test_track_b_insured_status_classification_oracle.py::test_classification_oracle_blind_fully_flag_still_has_one_first_start[CoverageCondition.EARNED_BASIS]", + "tests/test_track_b_insured_status_classification_oracle.py::test_classification_oracle_blind_fully_flag_still_has_one_first_start[CoverageCondition.SIMPLIFIED_PRE1951]" + ], + "failed": 4, + "pytest_summary": "4 failed in 2.73s", + "passed": 0, + "runtime_seconds": 2.73, + "exit_code": 1, + "killed": true, + "source_restored": true, + "restoration": "Runner execs mutation in module namespace only and asserts source bytes unchanged before printing OPEN_AUDIT.", + "oracle_test_sha256": "4ff36ba10c71ac077ec7a678353e420454e11bcb2f53b8b21816e4315d74b5f5" + }, + { + "name": "oracle_annual_placement_retry_removed", + "source_sha256": "1234c1cf5f199b92a102d71ad3c41f7a177ca242df626a97eaf6b4e9b889771d", + "changes": [ + { + "before": " if use_periods_only is None and not _outside_prior_periods(\n person, _qid(quarter)\n ):\n", + "after": " if False and use_periods_only is None and not _outside_prior_periods(\n person, _qid(quarter)\n ):\n" + } + ], + "spec_path": "scratch/review/round13-mutation-oracle_annual_placement_retry_removed.json", + "node": "tests/test_track_b_insured_status_classification_oracle.py::test_classification_oracle_annual_placement_can_delay_first_insured_quarter", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round13 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round13 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND13_MUTATION=scratch/review/round13-mutation-oracle_annual_placement_retry_removed.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round13_named.py -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_insured_status_classification_oracle.py::test_classification_oracle_annual_placement_can_delay_first_insured_quarter > scratch/review/round13-mutation-oracle_annual_placement_retry_removed.log 2>&1", + "log": "scratch/review/round13-mutation-oracle_annual_placement_retry_removed.log", + "audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_classification_oracle.py::test_classification_oracle_annual_placement_can_delay_first_insured_quarter" + ], + "failed": 1, + "pytest_summary": "1 failed in 7.07s", + "passed": 0, + "runtime_seconds": 7.07, + "exit_code": 1, + "killed": true, + "source_restored": true, + "restoration": "Runner execs mutation in module namespace only and asserts source bytes unchanged before printing OPEN_AUDIT.", + "oracle_test_sha256": "4ff36ba10c71ac077ec7a678353e420454e11bcb2f53b8b21816e4315d74b5f5" + }, + { + "name": "public_disability_start_filling_carry_removed", + "source_sha256": "1234c1cf5f199b92a102d71ad3c41f7a177ca242df626a97eaf6b4e9b889771d", + "changes": [ + { + "before": " resolved.update(credits=credits, treatment=use_periods_only)\n", + "after": " resolved.update()\n" + } + ], + "spec_path": "scratch/review/round13-mutation-public_disability_start_filling_carry_removed.json", + "node": "tests/test_track_b_insured_status_fix_round_13.py::test_disability_witness_uses_the_legal_annual_start_filling", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round13 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round13 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND13_MUTATION=scratch/review/round13-mutation-public_disability_start_filling_carry_removed.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round13_named.py -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_insured_status_fix_round_13.py::test_disability_witness_uses_the_legal_annual_start_filling > scratch/review/round13-mutation-public_disability_start_filling_carry_removed.log 2>&1", + "log": "scratch/review/round13-mutation-public_disability_start_filling_carry_removed.log", + "audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_13.py::test_disability_witness_uses_the_legal_annual_start_filling" + ], + "failed": 1, + "pytest_summary": "1 failed in 3.93s", + "passed": 0, + "runtime_seconds": 3.93, + "exit_code": 1, + "killed": true, + "source_restored": true, + "restoration": "Runner execs mutation in module namespace only and asserts source bytes unchanged before printing OPEN_AUDIT." + } + ], + "round_13_runner_source": "\"\"\"Run named invented-data conformance tests with open-event auditing.\"\"\"\n\nimport hashlib\nimport json\nimport os\nfrom pathlib import Path\nimport sys\n\nCOUNTS = {\"restricted_opens\": 0, \"subprocess.Popen\": 0, \"os.system\": 0}\nBARRED = {\n \"gates.yaml\", \"adjusted_poverty.py\", \"rows.py\",\n \"ssa_trust_fund_interest_rates_2026.json\",\n \"urban2010_cola_comparison.md\", \"urban2010_fra68_comparison.md\",\n \"boomers2004_uniform_cut_comparison.md\", \"minimum_benefits_comparison.md\",\n \"m6_projection_engine.md\", \"mint8_table_user_guide.source.html\",\n \"test_anchor_provenance_erratum.py\",\n}\n\n\ndef audit(event, arguments):\n if event == \"open\" and isinstance(arguments[0], (str, bytes)):\n path = os.fsdecode(arguments[0])\n name = Path(path).name\n if (\n name in BARRED\n or name.startswith((\"adjusted_poverty.\", \"rows.\"))\n or \"/PolicyEngine/psid-data/\" in path\n or \"/microcosm-launch-evidence/\" in path\n or \"/dynasim-refs/\" in path\n or \"/claude-501/\" in path\n ):\n COUNTS[\"restricted_opens\"] += 1\n raise RuntimeError(path)\n elif event in (\"subprocess.Popen\", \"os.system\"):\n COUNTS[event] += 1\n\n\ndef main():\n for name in (\"POPULACE_DYNAMICS_PSID_DIR\", \"POPULACE_DYNAMICS_EPUF_DIR\"):\n assert os.environ[name] == \"/nonexistent/trackb-round13\"\n assert sys.argv[1:]\n assert all(\n not argument.startswith(\"tests/\") or \".py\" in argument\n for argument in sys.argv[1:]\n )\n sys.addaudithook(audit)\n from populace_dynamics.track_b import insured_status as insured\n\n source_path = Path(insured.__file__)\n original = source_path.read_bytes()\n baseline_path = os.environ.get(\"TRACKB_ROUND13_SOURCE\")\n if baseline_path:\n baseline = Path(baseline_path).read_bytes()\n exec(compile(baseline, str(source_path), \"exec\"), insured.__dict__)\n print(\"BASELINE\", hashlib.sha256(baseline).hexdigest(), flush=True)\n spec_path = os.environ.get(\"TRACKB_ROUND13_MUTATION\")\n if spec_path:\n spec = json.loads(Path(spec_path).read_text())\n assert hashlib.sha256(original).hexdigest() == spec[\"source_sha256\"]\n source = original.decode()\n for change in spec[\"changes\"]:\n assert source.count(change[\"before\"]) == 1, change[\"before\"]\n source = source.replace(change[\"before\"], change[\"after\"], 1)\n exec(compile(source, str(source_path), \"exec\"), insured.__dict__)\n print(\"MUTATION\", spec[\"name\"], flush=True)\n import pytest\n\n try:\n return pytest.main(sys.argv[1:])\n finally:\n assert source_path.read_bytes() == original\n print(\"OPEN_AUDIT\", json.dumps(COUNTS, sort_keys=True), flush=True)\n\n\nif __name__ == \"__main__\":\n raise SystemExit(main())\n", + "round_13_note": "Sixteen isolated in-memory mutations were caught against the final source. Every run used named invented-data tests with nonexistent data roots, bounded threads, zero restricted opens and zero spawned-process audit events. Original source bytes were checked unchanged after each mutation. Oracle route-removal controls, coupled prior/current checks, first-start and annual-placement repairs, and the DISABILITY carried-filling repair all bite.", + "round_13_oracle_test_sha256": "4ffa46ffb24f7b8793eb2395a08e9f7c1eea4f784019dc8f3e17351a7f25718e", + "round_13_replay": "Write round_13_runner_source to scratch/review/run_round13_named.py. For each record, write name/source_sha256/changes to its spec_path, then execute its exact command. Each mutation applies only in memory and the runner verifies unchanged source bytes.", + "round_13_final_source_sha256": "1234c1cf5f199b92a102d71ad3c41f7a177ca242df626a97eaf6b4e9b889771d" } diff --git a/src/populace_dynamics/track_b/insured_status.py b/src/populace_dynamics/track_b/insured_status.py index b8c5cea73..96ecea19e 100644 --- a/src/populace_dynamics/track_b/insured_status.py +++ b/src/populace_dynamics/track_b/insured_status.py @@ -38,6 +38,20 @@ minimum or eligibility rule is claimed here. Fully-insured-only flags cannot bypass a failed recent-rule scan under upper credits, but retain a possible pre1956 alternate. Blindness and unknown prior history disable that scan. +After the stronger minimum proof, every route within the declared credit +envelope requires six QCs feasible by the immutable start horizon, except +blindness with a fully-insured-only flag. UNKNOWN prior history cannot +remove this floor. An established period's alternate witness must use a +single start that also clears prior-period overlap and the 1955 date limit; +credited endpoints remain eligible for its continuous clock. +UNKNOWN prior history also obeys a joint optimistic-clock proof: even +deleting every removable uncredited quarter cannot rescue a declaration +whose same credits fail the current route. Past blindness is allowed as +an unresolved prior basis. Known-history fully-route scans keep the first +insured start for each filling; a later clear quarter cannot repair an +overlapping first start. Blind fully-route declarations start at onset. +When construction resolves an annual-placement overlap, its selected +filling and prior treatment also supply the DISABILITY output witness. The declared pre1956 flag adds no route beyond the automatic alternate. Flag-specific conditions remain declared facts rather than adjudicated rules. Short DIB-entitled prior periods remain possible. Observable specialist credit @@ -61,7 +75,7 @@ from datetime import date, timedelta from enum import Enum from fractions import Fraction -from itertools import product +from itertools import combinations, product from math import prod from types import MappingProxyType @@ -955,6 +969,11 @@ def _pre1956_alternate_possible( first = max(_qid(person.disability_onset), 1952 * 4 + 2) last = min(_qid(month), 1955 * 4 + 3) for quarter in range(first, last + 1): + # One start must satisfy both the alternate and fixed chronology. + if person.current_disability_period_established and not ( + _outside_prior_periods(person, quarter) + ): + continue # RS00301.132 B.2/C.2: all prior periods are used or disregarded # for the continuous clock too; credited endpoints stay eligible. for use_periods in ( @@ -1123,13 +1142,16 @@ def _witness( *, onset=True, ignore_fully_insured=False, + use_periods_only=None, ): end = _qid(at) best = None # Source conflict us:oasdi-insured-prior-disability-favorable-disregard # CFR404.130(f): consider all prior periods or disregard all, favorably. for use_periods in ( - (True, False) if person.prior_disability_periods else (True,) + (use_periods_only,) + if use_periods_only is not None + else (True, False) if person.prior_disability_periods else (True,) ): prior_before = None rows, periods = _world( @@ -1412,10 +1434,19 @@ def _events(person, month, kind): return (month,) -def _decision_witness(person, credits, month, exit_month, kind): +def _decision_witness( + person, credits, month, exit_month, kind, *, use_periods_only=None +): best, qualifying = None, None for event in _events(person, month, kind): - witness = _witness(person, credits, event, exit_month, kind) + witness = _witness( + person, + credits, + event, + exit_month, + kind, + use_periods_only=use_periods_only, + ) if witness[0] and kind is InsuredTest.DISABILITY: return witness, _qdate(_qid(event)) if best is None or (witness[0], witness[1]) > (best[0], best[1]): @@ -1431,18 +1462,55 @@ def _period_end_unknown(person, month): ) -def _with_current_period(person, credits, month, exit_month): +def _with_current_period( + person, credits, month, exit_month, *, use_periods_only=None, resolved=None +): if not person.current_disability_period_established: return person, None fra = _fra_date(person) horizon = min(month, fra.replace(day=1)) witness, quarter = _decision_witness( - person, credits, horizon, exit_month, InsuredTest.DISABILITY + person, + credits, + horizon, + exit_month, + InsuredTest.DISABILITY, + use_periods_only=use_periods_only, ) if not witness[0]: raise InvalidFamilyInput( "Established current period has no insured disabled quarter" ) + if use_periods_only is None and not _outside_prior_periods( + person, _qid(quarter) + ): + # One annual placement and prior treatment must supply the first + # clear insured start. A favorable onset assignment that overlaps + # a prior cannot disprove a different, later first assignment. + rows, _ = _world(person, credits, _qid(horizon), exit_month, False) + options = [_assignment_candidates(*row) for row in rows.values()] + if prod(map(len, options)) > 4096: + _refuse( + InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, + "More than 4096 first-start annual placements", + ) + for choices in product(*options): + filling = { + year: (choice, 0) + for year, choice in zip(rows, choices, strict=True) + } + for treatment in (True, False): + try: + return _with_current_period( + person, + filling, + month, + exit_month, + use_periods_only=treatment, + resolved=resolved, + ) + except InvalidFamilyInput: + continue # 416(i)(2)(C), 404.321(a): onset day if insured then, otherwise # first day of the first later insured quarter. Application/duration # are administrative facts declared by the caller, never inferred. @@ -1472,16 +1540,15 @@ def _with_current_period(person, credits, month, exit_month): ): raise InvalidFamilyInput("Period continuity precedes insured start") period = DisabilityPeriod(start, end) - return ( - replace( - person, - prior_disability_periods=person.prior_disability_periods - + (period,), - prior_disability_periods_provenance=EarningsProvenance.OBSERVED, - prior_disability_periods_convention_id=None, - ), - start, + completed = replace( + person, + prior_disability_periods=person.prior_disability_periods + (period,), + prior_disability_periods_provenance=EarningsProvenance.OBSERVED, + prior_disability_periods_convention_id=None, ) + if resolved is not None and use_periods_only is not None: + resolved.update(credits=credits, treatment=use_periods_only) + return completed, start def _current_period_completions(person, completed, start, month): @@ -1543,9 +1610,13 @@ def _flagged_establishment_possible(person, years): Fully-route flags change only the fully insured prerequisite, leaving 404.130's independent recent-credit rule standing (404.110-.112; RS00301.101/.106/.470/.475; Act 213(c)). They are handled after that - numerical proof, and preserve possibility only if a recent rule or the - automatic pre1956 alternate remains possible. They bypass the ordinary - six-QC floor: 404.111 states no numeric minimum. The pre1956 flag adds + numerical proof. Except for blindness under 404.130(e), they retain + the six-QC recent floor by the start horizon, including UNKNOWN prior + history. UNKNOWN histories also face the joint optimistic-clock proof. + With known history they additionally need a first insured start clear + of prior quarters, or the automatic pre1956 alternate. Blindness + supplies insurance at onset and cannot delay that first start. The + pre1956 flag adds no route beyond the automatic alternate (RS00301.480 A/B.1); that alternate still requires twenty QCs. No flag's own conditions are adjudicated here. @@ -1614,31 +1685,169 @@ def _outside_prior_periods(person, quarter): ) -def _recent_rule_possible(person, credits, horizon, exit_month): +def _recent_rule_possible( + person, credits, horizon, exit_month, *, lower_credits=None +): """404.130(b)-(d) possibility, relaxing only the fully prerequisite. - Upper credits preserve every feasible assignment and favorable prior - treatment. Failure in every eligible quarter therefore disproves all - lower fillings. Complexity cannot disprove a specialist declaration. + A single filling must first qualify outside every supplied prior + quarter (404.321(a)). A later clear quarter cannot repair an earlier + insured start overlapping a prior. Enumerate annual placements and + every unresolved lower filling, retaining favorable prior treatment. + Complexity cannot disprove a specialist declaration. """ try: - for quarter in range(_qid(person.disability_onset), _qid(horizon) + 1): - if not _outside_prior_periods(person, quarter): - continue - if _witness( - person, - credits, - _qdate(quarter), - exit_month, - InsuredTest.DISABILITY, - ignore_fully_insured=True, - )[0]: - return True + candidates = range(_qid(person.disability_onset), _qid(horizon) + 1) + if all( + _outside_prior_periods(person, quarter) for quarter in candidates + ): + return any( + _witness( + person, + credits, + _qdate(quarter), + exit_month, + InsuredTest.DISABILITY, + ignore_fully_insured=True, + )[0] + for quarter in candidates + ) + rows, _ = _world(person, credits, _qid(horizon), exit_month, False) + options = [] + for year, row in rows.items(): + high = _assignment_candidates(*row) + if ( + lower_credits is not None + and lower_credits[year] != credits[year] + ): + fixed = tuple(q for q in lower_credits[year][0] if q in row[2]) + vacant = tuple(q for q in row[2] if q not in fixed) + minimum = min(lower_credits[year][1], len(vacant)) + maximum = max(map(len, high)) - len(fixed) + high = tuple( + tuple(sorted((*fixed, *choice))) + for count in range(minimum, maximum + 1) + for choice in combinations(vacant, count) + ) + options.append(high) + if prod(map(len, options)) > 4096: + return True + for choices in product(*options): + filling = { + year: (choice, 0) + for year, choice in zip(rows, choices, strict=True) + } + for treatment in (True, False): + for quarter in range( + _qid(person.disability_onset), _qid(horizon) + 1 + ): + if _witness( + person, + filling, + _qdate(quarter), + exit_month, + InsuredTest.DISABILITY, + ignore_fully_insured=True, + use_periods_only=treatment, + )[0]: + if _outside_prior_periods(person, quarter): + return True + break except InsuredConfigurationUnsupported: return True return False +def _unknown_prior_joint_shortfall(person, rows, horizon, fully_route): + """Disprove joint prior/current insurance on an optimistic clock. + + Every earliest prior needs fully insured status (404.130(a), (e)). + Allow historical blindness even when current blindness is false. + After its earliest possible start, delete every uncredited quarter + before the current start while retaining every QC, even interiors. + This relaxation dominates any number of real prior periods, whose + endpoints cannot delete credited quarters without also losing QCs. + An extra QC cannot hurt either a half-elapsed or a 20/40 test on this + clock. Upper-credit placements therefore bound every lower filling. + A special prior must itself have six QCs before age 31 (404.130(d)). + + Search at most 4096 annual placements; a larger space proves nothing. + This is only a necessary-condition proof, never a concrete witness. + The historical alternate is handled separately by the caller. + """ + options = [_assignment_candidates(*row) for row in rows.values()] + if prod(map(len, options)) > 4096: + return False + first = max(1937 * 4, _qid(_attain(person.birth_date, 21)) + 1) + age31 = _qid(_attain(person.birth_date, 31)) + onset = _qid(person.disability_onset) + last = _qid(horizon) + for choices in product(*options): + assigned = {q for annual in choices for q in annual} + earliest = None + if fully_route: + earliest = _qid(person.birth_date) + elif assigned: + # This is the earliest possible period of any medical type. + # No earlier period can supply exclusions for this test. + for quarter in range(min(assigned), min(onset, last) + 1): + if sum(q <= quarter for q in assigned) >= _requirement( + person, _qdate(quarter), for_disability=True + ): + earliest = quarter + break + + clock_first = min(first - 40, min(assigned, default=first)) + + def clock( + quarter, + clock_first=clock_first, + earliest=earliest, + assigned=assigned, + ): + # The candidate itself cannot be excluded. Before the first + # possible prior, every elapsed quarter remains unavoidable. + return tuple( + q + for q in range(clock_first, quarter + 1) + if earliest is None + or q < earliest + or q == quarter + or q in assigned + ) + + def special_recent(quarter, clock=clock, assigned=assigned): + counted = clock(quarter) + elapsed = tuple(q for q in counted if q >= first) + if len(elapsed) < 12: + window, required = counted[-12:], 6 + elif len(elapsed) > 40: + window, required = elapsed[-40:], 20 + else: + window, required = elapsed, max(6, len(elapsed) // 2) + return len(set(window) & assigned) >= required + + # Optimistically permit every prior-special start, including a + # blindness prefix, but never credits earned at/after age 31. + special = earliest is not None and any( + special_recent(quarter) + for quarter in range( + max(clock_first, earliest), + min( + age31, + _qid(person.disability_onset - timedelta(days=1)) + 1, + last, + ), + ) + ) + for quarter in range(onset, last + 1): + if len(set(clock(quarter)[-40:]) & assigned) >= 20: + return False + if (quarter < age31 or special) and special_recent(quarter): + return False + return True + + def _could_establish_current_period( person, years, @@ -1661,6 +1870,13 @@ def _could_establish_current_period( prior period. Fixed quarter overlap is checked before searching. Unresolved prior histories and more than 4096 overlap fillings that survive that check remain outside the exact ordinary predicate. + The stronger known-history minimum proof stays first. Except for + blindness with a fully-route flag, six QCs must then be feasible by + the immutable horizon before UNKNOWN prior history can preserve a + route. The alternate's start must itself clear prior-period overlap. + UNKNOWN prior histories face an optimistic joint clock that permits + past blindness and dominates every number of real prior periods. + Fully-route starts obey 404.321(a), including onset with blindness. """ if not person.current_disability_period_established: return True @@ -1687,16 +1903,31 @@ def _could_establish_current_period( ): return False fully_route = bool(person.conditions & _FULLY_INSURED_ROUTE_CONDITIONS) - if fully_route and ( - person.statutory_blindness - or person.prior_disability_periods_provenance + if fully_route and person.statutory_blindness: + return _outside_prior_periods(person, _qid(person.disability_onset)) + # 404.130(b)-(d) and RS00301.480 retain at least six QCs even + # when UNKNOWN prior history changes the window or special route. + rows, _ = _world(person, credits, _qid(horizon), exit_month, False) + horizon_qcs = sum(len(_assign_qcs(*row)) for row in rows.values()) + if horizon_qcs < 6: + return False + if ( + 6 <= horizon_qcs + and not person.statutory_blindness + and person.disability_onset >= date(1956, 1, 1) + and person.prior_disability_periods_provenance is EarningsProvenance.UNKNOWN + and _unknown_prior_joint_shortfall(person, rows, horizon, fully_route) ): - return True - if not fully_route and maximum_qcs < 6: return False + if ( + fully_route + and person.prior_disability_periods_provenance + is EarningsProvenance.UNKNOWN + ): + return True if fully_route and _recent_rule_possible( - person, credits, horizon, exit_month + person, credits, horizon, exit_month, lower_credits=lower_credits ): return True if _pre1956_alternate_possible( @@ -1705,9 +1936,6 @@ def _could_establish_current_period( return True if fully_route: return False - rows, _ = _world(person, credits, _qid(horizon), exit_month, False) - if sum(len(_assign_qcs(*row)) for row in rows.values()) < 6: - return False if ( person.prior_disability_periods_provenance is EarningsProvenance.UNKNOWN @@ -1858,10 +2086,20 @@ def insured_status( Foreign credits preserve an unmodeled route before credit-count proofs; no totalization minimum or eligibility rule is claimed. A conservative minimum-QC proof precedes fully-insured-only flags and boundary - complexity, except for blindness and unknown prior history. Fully-route - flags bypass the six-QC floor but must retain a recent-rule witness or - automatic pre1956 alternate when that proof applies. Blindness and - unknown prior histories preserve their named flags without this scan. + complexity, except for blindness and unknown prior history. A separate + six-QC floor uses credits feasible by the immutable start horizon; + only blindness with a fully-route flag bypasses it. UNKNOWN prior + history changes windows or special eligibility, never this floor. + With known nonblind history, fully-route flags must retain a recent + first insured start outside prior quarters, or automatic pre1956 + alternate. UNKNOWN history also faces a joint optimistic-clock proof + permitting past blindness; survival never claims a concrete history. + Blind fully-route insurance fixes the first start at onset. The + alternate must use one + start clearing fixed overlap, the horizon and its 1955 date limit; + its prior-period clock and credited endpoints remain unchanged. + A resolved annual start supplies the same filling and prior treatment + to the DISABILITY output, rather than a new favorable onset assignment. The pre1956 flag adds no route beyond the automatic alternate. A flag's own conditions remain declared facts and are not tested. History validation runs first. Uncomputable QC rows use bounded @@ -1946,6 +2184,7 @@ def insured_status( # established period never existed (404.320(a),404.130(f)). Unknown # prior periods cannot be mixed selectively with the current period. uncertain_current_start = False + lo_resolution, hi_resolution = {}, {} if prior_unknown: lo_person = hi_person = person lo_start = hi_start = None @@ -1964,7 +2203,11 @@ def insured_status( else: try: lo_person, lo_start = _with_current_period( - person, lower, month, coverage_end_month + person, + lower, + month, + coverage_end_month, + resolved=lo_resolution, ) hi_person, hi_start = ( _with_current_period( @@ -1972,6 +2215,7 @@ def insured_status( upper, month, coverage_end_month, + resolved=hi_resolution, ) if unknown else (lo_person, lo_start) @@ -2030,12 +2274,42 @@ def insured_status( (person,) if kind is InsuredTest.DISABILITY else hi_completions ) lo_candidates = [ - _decision_witness(p, lower, month, coverage_end_month, kind) + _decision_witness( + p, + ( + lo_resolution.get("credits", lower) + if kind is InsuredTest.DISABILITY + else lower + ), + month, + coverage_end_month, + kind, + use_periods_only=( + lo_resolution.get("treatment") + if kind is InsuredTest.DISABILITY + else None + ), + ) for p in decision_lo_people ] hi_candidates = ( [ - _decision_witness(p, upper, month, coverage_end_month, kind) + _decision_witness( + p, + ( + hi_resolution.get("credits", upper) + if kind is InsuredTest.DISABILITY + else upper + ), + month, + coverage_end_month, + kind, + use_periods_only=( + hi_resolution.get("treatment") + if kind is InsuredTest.DISABILITY + else None + ), + ) for p in decision_hi_people ] if unknown diff --git a/tests/README-tiers.md b/tests/README-tiers.md index 95d72212b..309d07d1f 100644 --- a/tests/README-tiers.md +++ b/tests/README-tiers.md @@ -39,9 +39,9 @@ pytest --collect-only -q -m oracle_policyengine | tail -1 | Tier | Tests at HEAD | |---|---:| -| `unit` | 20,971 | +| `unit` | 21,140 | | `artifact` | 4,271 | | `integration_psid` | 1,471 | | `reproduction_legacy` | 520 | | `oracle_policyengine` | 308 | -| **Total** | **27,541** | +| **Total** | **27,710** | diff --git a/tests/test_track_b_insured_status_classification_oracle.py b/tests/test_track_b_insured_status_classification_oracle.py new file mode 100644 index 000000000..34bc9daee --- /dev/null +++ b/tests/test_track_b_insured_status_classification_oracle.py @@ -0,0 +1,1188 @@ +"""Bounded independent classification oracle for invented declarations. + +Verification class: statutory conformance. No population, behavioral, or +forecast claim. The oracle uses public declaration types, plain quarter +arithmetic, and exhaustive annual placements; it calls no implementation +helper. CFR 404.110/.130/.131/.320/.321 and POMS RS 00301.132/.140/.147/.480 +supply the rules. + +The deterministic lattice contains more than 3,000 declarations, with at most +two UNKNOWN credit years (each completed by every permitted quarter subset, up +to sixteen), two observed prior periods, and one UNKNOWN prior period. UNKNOWN +history is completed by the empty history and every one-period quarter interval +from the first possible credited quarter through the onset quarter, with the +end clamped before the onset day. Each start must itself be insured. Special +provenance is admitted only for an under31 witness without 20/40. Earlier +blindness may supply insurance through fully insured status even when current +blindness is absent. A second bounded class combines a blind prefix from birth +through the quarter before the first QC with every later insured special +interval. This is an explicit bound: arbitrary two-period histories and three +or more UNKNOWN periods are not exhausted. Named negative examples have +separate impossibility proofs that exclude additional periods; a bounded search +alone is not such a proof. + +UNKNOWN endings enumerate every month end through query, plus the statutory +FRA/death cap. Modern queries are at most four elapsed quarters after onset; +historical queries are in 1968 or 1973 and have known endings. Annual totals +have at most two partly credited observed years; selected cases have at most +192 complete annual placements each. Raw earnings, foreign credits, credit- +adding flags, complex boundary refusals, administrative application facts and +SSPA211 are outside this oracle. Declarations use female sex; the male fully +insured transition for cohorts born before 1913 is outside the bound. The +separate round 13 regression module covers credit-adding routes. Known prior +periods are declared established facts and are not re-adjudicated. This oracle +checks declaration classification, not coherence across separate assignment +witnesses returned for individual statuses and DLI. +""" + +from __future__ import annotations + +import calendar +from dataclasses import dataclass, replace +from datetime import date, timedelta +from fractions import Fraction +from functools import lru_cache +from itertools import combinations, product + +import pytest +from hypothesis import example, given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as rule +from populace_dynamics.track_b.gross_benefits import count_family_outcomes + +pytestmark = pytest.mark.unit +OBSERVED = rule.EarningsProvenance.OBSERVED +UNKNOWN = rule.EarningsProvenance.UNKNOWN +WEIGHT = Fraction(17, 9) +FULLY_FLAGS = ( + rule.CoverageCondition.DEEMED_FULLY_INSURED, + rule.CoverageCondition.TRANSITIONAL_INSURED, + rule.CoverageCondition.EARNED_BASIS, + rule.CoverageCondition.SIMPLIFIED_PRE1951, +) +ALTERNATE_FLAG = rule.CoverageCondition.DISABILITY_BEFORE_1956 +FLAG_SETS = ( + (), + *((flag,) for flag in FULLY_FLAGS), + (ALTERNATE_FLAG,), + *((flag, ALTERNATE_FLAG) for flag in FULLY_FLAGS), + (FULLY_FLAGS[0], FULLY_FLAGS[1]), +) + + +def _quarter(value): + return value.year * 4 + (value.month - 1) // 3 + + +def _quarter_date(value): + year, part = divmod(value, 4) + return date(year, part * 3 + 1, 1) + + +def _attained(birth, age): + year = birth.year + age + day = min(birth.day, calendar.monthrange(year, birth.month)[1]) + return date(year, birth.month, day) - timedelta(days=1) + + +def _fra(birth): + cohort = (birth - timedelta(days=1)).year + months = 780 + if 1938 <= cohort <= 1942: + months += (cohort - 1937) * 2 + elif 1943 <= cohort <= 1954: + months = 792 + elif 1955 <= cohort <= 1959: + months = 792 + (cohort - 1954) * 2 + elif cohort >= 1960: + months = 804 + index = birth.year * 12 + birth.month - 1 + months + year, month = divmod(index, 12) + return date(year, month + 1, birth.day) - timedelta(days=1) + + +def _month_end(value): + return value.replace(day=calendar.monthrange(value.year, value.month)[1]) + + +def _minus_two_months(value): + year, month = divmod(value.year * 12 + value.month - 3, 12) + return date(year, month + 1, 1) + + +@dataclass(frozen=True) +class EnumeratedPeriod: + """An arithmetic completion, independent of production validation.""" + + start: date + end: date + special_insured: bool = False + + +@dataclass(frozen=True) +class Declaration: + person: rule.Person + month: date + # Each entry is (year, fixed quarters or None, annual count or None). + # Both None represents UNKNOWN, independently completed by all subsets. + annual: tuple[tuple[int, tuple[int, ...] | None, int | None], ...] + exit_month: date | None = None + + +def _history(case): + rows = {} + for year, fixed, count in case.annual: + if fixed is None and count is None: + rows[year] = rule.CoverageYear(UNKNOWN) + elif year < 1978: + assert fixed is not None + rows[year] = rule.CoverageYear( + OBSERVED, + qc_quarters=tuple(year * 4 + q in fixed for q in range(4)), + ) + else: + rows[year] = rule.CoverageYear(OBSERVED, qc_count=count) + return rows + + +def _declaration( + *, + birth=date(1960, 2, 2), + onset=date(2000, 1, 15), + end=date(2000, 12, 31), + month=date(2001, 1, 1), + flags=(), + blind=False, + established=True, + periods=(), + prior_unknown=False, + through=None, + death=None, + exit_month=None, + counts=(), + fixed=(), + unknown_years=(), +): + person = rule.Person( + birth, + sex=rule.Sex.FEMALE, + death_date=death, + disability_onset=onset, + statutory_blindness=blind, + conditions=frozenset(flags), + prior_disability_periods=periods, + prior_disability_periods_provenance=( + UNKNOWN if prior_unknown else OBSERVED + ), + current_disability_period_established=established, + current_disability_period_provenance=( + UNKNOWN if established is None else OBSERVED + ), + current_disability_period_end=end if established else None, + current_disability_period_end_provenance=( + OBSERVED if end is not None and established else UNKNOWN + ), + current_disability_period_continues_through=through, + current_disability_period_continues_through_provenance=( + OBSERVED if through is not None else UNKNOWN + ), + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + last_year = min( + month.year, + exit_month.year if exit_month else month.year, + death.year if death else month.year, + ) + counts = dict(counts) + fixed = frozenset(fixed) + annual = [] + for year in range(max(1937, birth.year), last_year + 1): + if year in unknown_years: + annual.append((year, None, None)) + elif year < 1978: + annual.append( + (year, tuple(q for q in sorted(fixed) if q // 4 == year), 0) + ) + else: + annual.append((year, None, counts.get(year, 0))) + return Declaration(person, month, tuple(annual), exit_month) + + +def _placements(case): + person = case.person + last = min( + _quarter(case.month), + _quarter(person.death_date) if person.death_date else 99999, + _quarter(case.exit_month) if case.exit_month else 99999, + ) + alternatives = [] + for year, fixed, count in case.annual: + slots = tuple( + q + for q in range(year * 4, year * 4 + 4) + if _quarter(person.birth_date) <= q <= last + ) + if fixed is not None: + alternatives.append((fixed,)) + elif count is None: + alternatives.append( + tuple( + choice + for number in range(len(slots) + 1) + for choice in combinations(slots, number) + ) + ) + else: + alternatives.append( + tuple(combinations(slots, min(count, len(slots)))) + ) + for chosen in product(*alternatives): + yield frozenset(q for annual in chosen for q in annual) + + +@lru_cache(maxsize=32768) +def _fully_needed(person, start, periods): + first = max(1951, _attained(person.birth_date, 21).year + 1) + last = min(start.year, _attained(person.birth_date, 62).year) + if person.death_date is not None: + last = min(last, person.death_date.year) + return min( + 40, + max( + 6, + sum( + not any(p.start.year <= year <= p.end.year for p in periods) + for year in range(first, last) + ), + ), + ) + + +def _usable(credits, start, periods): + return frozenset( + q + for q in credits + if q <= start + and not any( + _quarter(period.start) < q < _quarter(period.end) + for period in periods + ) + ) + + +def _elapsed_quarters(first, last, periods, credits): + return tuple( + q + for q in range(first, last + 1) + if not any( + _quarter(period.start) <= q <= _quarter(period.end) + and q not in credits + for period in periods + ) + ) + + +def _lookback(start, number, periods, credits): + answer = [] + while len(answer) < number: + if not any( + _quarter(period.start) <= start <= _quarter(period.end) + and start not in credits + for period in periods + ): + answer.append(start) + start -= 1 + return frozenset(answer) + + +@lru_cache(maxsize=32768) +def _ordinary_routes( + person, credits, start, periods, fully_flag, *, special=False +): + """All routes for one fixed placement, start and prior treatment.""" + used = _usable(credits, start, periods) + fully = fully_flag or len(used) >= _fully_needed( + person, _quarter_date(start), periods + ) + if not fully: + return () + if person.statutory_blindness: + return ("blindness",) + routes = [] + if len(used & _lookback(start, 40, periods, used)) >= 20: + routes.append("20_of_40") + young = start < _quarter(_attained(person.birth_date, 31)) + subsequent = special or any(p.special_insured for p in periods) + if young or subsequent: + elapsed = _elapsed_quarters( + max(1937 * 4, _quarter(_attained(person.birth_date, 21)) + 1), + start, + periods, + used, + ) + if len(elapsed) < 12: + window, needed = _lookback(start, 12, periods, used), 6 + elif len(elapsed) > 40: + window, needed = frozenset(elapsed[-40:]), 20 + else: + window, needed = frozenset(elapsed), max(6, len(elapsed) // 2) + if len(used & window) >= needed: + routes.append("under31" if young else "subsequent_special") + return tuple(routes) + + +def _endings(case): + person = case.person + if person.current_disability_period_end is not None: + return (person.current_disability_period_end,) + cap = _fra(person.birth_date).replace(day=1) - timedelta(days=1) + if person.death_date is not None: + cap = min(cap, person.death_date) + through = person.current_disability_period_continues_through + first = person.disability_onset + candidates = [] + index = first.year * 12 + first.month - 1 + stop = min(case.month, cap).year * 12 + min(case.month, cap).month - 1 + for value in range(index, stop + 1): + year, month = divmod(value, 12) + ending = min(_month_end(date(year, month + 1, 1)), cap) + if through is None or ending >= through: + candidates.append(ending) + if cap > case.month and (through is None or cap >= through): + candidates.append(cap) + return tuple(dict.fromkeys(candidates)) + + +def _start_horizon(case, ending): + person = case.person + horizon = min(case.month, ending, _fra(person.birth_date).replace(day=1)) + fra_end = _fra(person.birth_date).replace(day=1) - timedelta(days=1) + # Only an actually declared pre-February-1981 ending implies recovery; + # an UNKNOWN completion may instead be an adjudicated paragraph(c) end. + declared = person.current_disability_period_end + if ( + declared is not None + and declared < date(1981, 2, 1) + and declared.replace(day=1) < fra_end.replace(day=1) + and ( + person.death_date is None + or declared.replace(day=1) < person.death_date.replace(day=1) + ) + ): + horizon = min(horizon, _minus_two_months(declared)) + if person.death_date is not None: + horizon = min(horizon, person.death_date) + if person.current_disability_period_continues_through is not None: + horizon = min( + horizon, person.current_disability_period_continues_through + ) + return _quarter(horizon) + + +def _alternate(case, credits, start, periods, prior): + person = case.person + if not 1952 * 4 + 2 <= start <= 1955 * 4 + 3: + return False + # The period-covered reading is the conservative existing contract. + # Every completion's guaranteed disabled months end at the observed + # end/continuity minus two, clamped at onset; UNKNOWN ends share onset. + dated = ( + person.current_disability_period_end + or person.current_disability_period_continues_through + ) + covered = person.disability_onset + if dated is not None: + covered = max(covered, _minus_two_months(dated)) + last = min( + _quarter(case.month), + _quarter(_fra(person.birth_date).replace(day=1) - timedelta(days=1)), + _quarter(covered), + 1960 * 4 + 2, + ) + for candidate in range(_quarter(person.disability_onset), last + 1): + # The exclusion can use either favorable treatment, independently + # of the treatment supplying this alternate clock. + for treatment in (prior, ()): + used = _usable(credits, candidate, treatment) + if len(used & _lookback(candidate, 40, treatment, used)) >= 20: + return False + used = _usable(credits, start, periods) + continuous = _elapsed_quarters(1951 * 4, start - 1, periods, used) + return len(used) >= 20 and len(continuous) >= 6 and set(continuous) <= used + + +def _unknown_priors(case, credits, fully_flag): + person = case.person + yield () + if not credits: + return + stop = _quarter(person.disability_onset) + for first in range(min(credits), stop + 1): + routes = _ordinary_routes(person, credits, first, (), fully_flag) + blind_prior = _ordinary_routes( + replace(person, statutory_blindness=True), + credits, + first, + (), + fully_flag, + ) + if not routes and not blind_prior: + continue + for last in range(first, stop + 1): + # At quarter resolution a one-month DIB-entitled period can + # occupy even a single quarter (Act216(i)(2)(A),404.315(a)(4)). + end = min( + _month_end( + _quarter_date(last).replace( + month=(_quarter_date(last).month + 2) + ) + ), + person.disability_onset - timedelta(days=1), + ) + for special in ( + (False, True) + if "under31" in routes and "20_of_40" not in routes + else (False,) + ): + yield ( + EnumeratedPeriod( + max(person.birth_date, _quarter_date(first)), + end, + special_insured=special, + ), + ) + + # The two-period bound also admits a historical blind prefix ending + # just before the first credited quarter, followed by a special prior. + # With a fully flag the prefix needs no own QCs. Its earliest start is + # the birth quarter; its end preserves every QC and removes every + # earlier elapsed quarter, so this is the favorable prefix representative. + if not fully_flag or min(credits) >= _quarter( + _attained(person.birth_date, 31) + ): + return + prefix_end = _quarter_date(min(credits)) - timedelta(days=1) + if prefix_end < person.birth_date: + return + prefix = EnumeratedPeriod(person.birth_date, prefix_end) + for first in range( + min(credits), + min(stop, _quarter(_attained(person.birth_date, 31)) - 1) + 1, + ): + routes = _ordinary_routes( + person, credits, first, (prefix,), fully_flag + ) + if "under31" not in routes or "20_of_40" in routes: + continue + for last in range(first, stop + 1): + end = min( + _month_end( + _quarter_date(last).replace( + month=(_quarter_date(last).month + 2) + ) + ), + person.disability_onset - timedelta(days=1), + ) + yield ( + prefix, + EnumeratedPeriod( + _quarter_date(first), end, special_insured=True + ), + ) + + +def _has_valid_filling(case): + # Individual fully flags have identical oracle semantics; the alternate + # flag adds no route. Canonicalization avoids repeating the enumeration. + canonical = ( + (FULLY_FLAGS[0],) + if set(case.person.conditions) & set(FULLY_FLAGS) + else () + ) + return _enumerated_filling( + replace( + case, person=replace(case.person, conditions=frozenset(canonical)) + ) + ) + + +@lru_cache(maxsize=16384) +def _enumerated_filling(case): + person = case.person + # UNKNOWN establishment always has the absent-period completion. + if person.current_disability_period_established is not True: + return True + fully_flag = bool(set(person.conditions) & set(FULLY_FLAGS)) + for credits in _placements(case): + histories = ( + _unknown_priors(case, credits, fully_flag) + if person.prior_disability_periods_provenance is UNKNOWN + else (person.prior_disability_periods,) + ) + for prior in histories: + for ending in _endings(case): + starts = range( + _quarter(person.disability_onset), + _start_horizon(case, ending) + 1, + ) + for periods in ((prior, ()) if prior else ((),)): + # 404.321(a) fixes the first insured quarter. A later + # clear quarter cannot repair an already insured but + # overlapping onset quarter for this same filling. + first_ordinary = next( + ( + start + for start in starts + if _ordinary_routes( + person, + credits, + start, + periods, + fully_flag, + special=any(p.special_insured for p in prior), + ) + ), + None, + ) + if first_ordinary is not None and not any( + _quarter(p.start) <= first_ordinary <= _quarter(p.end) + for p in prior + ): + return True + for start in starts: + if any( + _quarter(p.start) <= start <= _quarter(p.end) + for p in prior + ): + continue + if _alternate(case, credits, start, periods, prior): + return True + return False + + +def _check_classification(case): + possible = _has_valid_filling(case) + rows = [] + try: + rows.append( + rule.evaluate_insured_status( + "classification-oracle", + WEIGHT, + lambda: rule.insured_status( + case.person, + _history(case), + case.month, + test=rule.InsuredTest.FULLY, + coverage_end_month=case.exit_month, + ), + ) + ) + except rule.InvalidFamilyInput: + assert not possible, f"oracle found a concrete filling: {case!r}" + else: + assert possible, f"oracle found no valid filling: {case!r}" + row = rows[0] + assert (row.result is None) != (row.unsupported is None) + if row.unsupported is not None: + assert isinstance( + row.unsupported.reason, rule.InsuredUnsupportedReason + ) + counts = count_family_outcomes(rows) + assert counts.rows == int(possible) + assert counts.weight == WEIGHT * int(possible) + assert counts.unsupported_rows == sum( + row.unsupported is not None for row in rows + ) + assert counts.unsupported_weight == WEIGHT * counts.unsupported_rows + + +def _counts(total, first): + answer = [] + while total: + amount = min(total, 4) + answer.append((first, amount)) + total -= amount + first += 1 + return tuple(answer) + + +def _modern_case(age, total, placement, flags, blind, prior, established=True): + onset_year = 2022 + birth = date(onset_year - age, 2, 2) + first = 2016 if placement == "recent" else max(birth.year, 1978) + periods = () + if prior in ("one", "two", "special"): + periods = ( + rule.DisabilityPeriod( + date(2010, 1, 1), + date(2012, 12, 31), + special_insured=prior == "special", + ), + ) + if prior == "two": + periods += ( + rule.DisabilityPeriod(date(2014, 1, 1), date(2014, 12, 31)), + ) + return _declaration( + birth=birth, + onset=date(2022, 1, 15), + end=date(2022, 12, 31), + month=date(2023, 1, 1), + flags=flags, + blind=blind, + established=established, + periods=periods, + prior_unknown=prior == "unknown", + counts=_counts(total, first), + ) + + +@pytest.mark.parametrize("flags", FLAG_SETS) +def test_classification_oracle_modern_lattice(flags): + # 11 * 4 * 6 * 2 * 2 * 3 = 3,168 declarations. UNKNOWN priors use + # the focused completion lattice below, avoiding redundant scans. + for age, total, placement, blind, established in product( + (24, 29, 42, 60), + (0, 5, 6, 19, 20, 24), + ("old", "recent"), + (False, True), + (False, True, None), + ): + _check_classification( + _modern_case( + age, total, placement, flags, blind, "none", established + ) + ) + + +@pytest.mark.parametrize("flags", FLAG_SETS) +def test_classification_oracle_prior_and_unknown_completions(flags): + for prior, total in product( + ("one", "two", "special", "unknown"), (0, 5, 6, 20) + ): + _check_classification( + _modern_case(42, total, "recent", flags, False, prior) + ) + for total, unknown_at in product((0, 5, 6, 19, 20), (2021, 2023)): + case = _modern_case(42, total, "recent", flags, False, "none") + case = replace( + case, + annual=tuple( + (year, None, None) if year == unknown_at else row + for row in case.annual + for year in (row[0],) + ), + ) + _check_classification(case) + + +@pytest.mark.parametrize("flags", FLAG_SETS) +def test_classification_oracle_historical_boundary_lattice(flags): + for birth_year, onset_year, total, prior_end in product( + (1890, 1900, 1910), + (1952, 1955, 1956), + (19, 20), + (None, (1955, 9, 30), (1955, 11, 30)), + ): + if prior_end is not None and onset_year < 1955: + continue + onset = date(onset_year, 12, 15) + if prior_end is not None and date(*prior_end) >= onset: + continue + # The 1890 cohort is past FRA by late 1955: it belongs on the + # absent/UNKNOWN side of the declaration boundary, not a malformed + # Person constructor on the established side. + established = onset < _fra(date(birth_year, 2, 2)).replace(day=1) + periods = ( + (rule.DisabilityPeriod(date(1952, 7, 1), date(*prior_end)),) + if prior_end is not None + else () + ) + fixed = ( + *range(1938 * 4, 1938 * 4 + total - 6), + *range(1951 * 4, 1952 * 4 + 2), + ) + _check_classification( + _declaration( + birth=date(birth_year, 2, 2), + onset=onset, + end=date(onset_year + 1, 3, 31), + month=date(1968, 1, 1), + flags=flags, + established=established, + periods=periods, + fixed=fixed, + ) + ) + + +@pytest.mark.parametrize("flags", FLAG_SETS) +def test_classification_oracle_dated_bounds(flags): + for end_month, through_month, death_month, exit_month in ( + (2, None, None, None), + (3, None, None, None), + (4, None, None, None), + (None, None, None, None), + (None, 2, None, None), + (None, 4, None, None), + (None, None, 2, None), + (None, None, 4, None), + (None, None, None, date(2021, 12, 1)), + ): + for total in (5, 6, 19, 20): + _check_classification( + _declaration( + birth=date(1980, 2, 2), + onset=date(2022, 1, 15), + end=( + _month_end(date(2022, end_month, 1)) + if end_month + else None + ), + month=date(2022, 7, 1), + through=( + date(2022, through_month, 15) + if through_month + else None + ), + death=( + date(2022, death_month, 20) if death_month else None + ), + exit_month=exit_month, + flags=flags, + counts=_counts(total, 2017), + ) + ) + + +def _property_case( + scenario, age, total, blind, flag, prior, phase, established +): + flags = FLAG_SETS[flag] + if scenario == "modern": + return _modern_case( + age, + total, + "recent" if phase % 2 else "old", + flags, + blind, + prior, + established, + ) + if scenario == "historical": + birth = date((1890, 1900, 1910)[phase % 3], 2, 2) + onset = date((1952, 1955, 1956)[(age + phase) % 3], 12, 15) + periods = () + if phase % 2 and onset.year >= 1955: + periods = ( + rule.DisabilityPeriod(date(1952, 7, 1), date(1955, 11, 30)), + ) + number = 20 if blind else 19 + return _declaration( + birth=birth, + onset=onset, + end=date(onset.year + 1, 3, 31), + month=date(1968, 1, 1), + flags=flags, + established=onset < _fra(birth).replace(day=1), + periods=periods, + fixed=( + *range(1938 * 4, 1938 * 4 + number - 6), + *range(1951 * 4, 1952 * 4 + 2), + ), + ) + if scenario == "dated": + end, through, death, exit_month = ( + (date(2022, 2, 28), None, None, None), + (date(2022, 3, 31), None, None, None), + (date(2022, 4, 30), None, None, None), + (None, None, None, None), + (None, date(2022, 2, 15), None, None), + (None, date(2022, 4, 15), None, None), + (None, None, date(2022, 2, 20), None), + (None, None, date(2022, 4, 20), None), + (None, None, None, date(2021, 12, 1)), + )[phase] + return _declaration( + birth=date(1980, 2, 2), + onset=date(2022, 1, 15), + end=end, + month=date(2022, 7, 1), + flags=flags, + through=through, + death=death, + exit_month=exit_month, + counts=_counts((5, 6, 19, 20)[phase % 4], 2017), + ) + if scenario == "annual": + return _declaration( + onset=date(2000, 2, 15), + end=date(2000, 2, 29) if phase % 2 else date(2000, 12, 31), + flags=flags, + periods=( + rule.DisabilityPeriod( + date(1999, 1, 1), + date(2000, 1, 31) if blind else date(1999, 12, 31), + ), + ), + counts=( + (1995, 4), + (1996, 4), + (1997, 4), + (1998, 4), + (1999, 3), + (2000, (0, 1, 4)[phase % 3]), + ), + ) + if scenario == "unknown-years": + return _declaration( + birth=date(1999, 2, 2), + onset=date(2022, 1, 15), + end=date(2022, 12, 31), + month=date(2023, 1, 1), + flags=flags, + counts=((2020, 1 + phase % 2),), + unknown_years=(2021, 2023), + ) + assert scenario == "special" + periods = ( + () + if phase % 2 + else ( + rule.DisabilityPeriod( + date(2012, 4, 1), date(2021, 12, 31), special_insured=True + ), + ) + ) + return _declaration( + birth=date(1990, 2, 2), + onset=date(2022, 1, 15), + end=date(2022, 12, 31), + month=date(2023, 1, 1), + flags=flags, + periods=periods, + prior_unknown=bool(phase % 2), + counts=_counts(5 + int(blind), 2011), + ) + + +@settings(max_examples=48, deadline=None, derandomize=True) +@example( + scenario="modern", + age=42, + total=0, + blind=False, + flag=0, + prior="unknown", + phase=1, + established=True, +) +@given( + scenario=st.sampled_from( + ("modern", "historical", "dated", "annual", "unknown-years", "special") + ), + age=st.sampled_from((24, 29, 42, 60)), + total=st.sampled_from((0, 5, 6, 19, 20, 24)), + blind=st.booleans(), + flag=st.integers(0, len(FLAG_SETS) - 1), + prior=st.sampled_from(("none", "unknown")), + phase=st.integers(0, 8), + established=st.sampled_from((False, True, None)), +) +def test_classification_oracle_hypothesis( + scenario, + age, + total, + blind, + flag, + prior, + phase, + established, +): + _check_classification( + _property_case( + scenario, age, total, blind, flag, prior, phase, established + ) + ) + + +def test_classification_oracle_requires_ordinary_recent_route(): + """A fully flag supplies no QCs but can make a 20/40 filling valid.""" + _check_classification( + _declaration( + birth=date(1940, 2, 2), + flags=(FULLY_FLAGS[0],), + counts=_counts(20, 1995), + ) + ) + + +def test_classification_oracle_requires_alternate_route(): + """Twenty lifetime QCs and the six-quarter clock need the alternate.""" + _check_classification( + _declaration( + birth=date(1900, 2, 2), + onset=date(1952, 7, 15), + end=date(1953, 12, 31), + month=date(1968, 1, 1), + flags=(FULLY_FLAGS[0],), + fixed=( + *range(1938 * 4, 1941 * 4 + 2), + *range(1951 * 4, 1952 * 4 + 2), + ), + ) + ) + + +def test_classification_oracle_unknown_prior_must_jointly_insure_current(): + """Earliest insured prior has a credited endpoint, leaving 14 quarters. + + Six QCs first exist in 2017Q2. Under31 insurance can establish a first + prior then, but using every remaining prior quarter through 2021Q4 + still leaves fourteen elapsed quarters at the earliest current start. + Seven QCs are needed. An additional prior cannot precede that first + insured start or remove its credited endpoint or any current quarter; + no multi-period completion can improve the bound. + """ + case = _modern_case(29, 6, "recent", (), False, "unknown") + assert not _has_valid_filling(case) + _check_classification(case) + + +@pytest.mark.parametrize("flag", FULLY_FLAGS) +def test_classification_oracle_unknown_prior_cannot_invent_special_eligibility( + flag, +): + """The first QCs are after age31; no special prior can exist.""" + case = _modern_case(42, 6, "recent", (flag,), False, "unknown") + assert not _has_valid_filling(case) + _check_classification(case) + + +@pytest.mark.parametrize("flags", FLAG_SETS) +def test_classification_oracle_onset_quarter_and_credited_endpoint(flags): + for prior_end, credit_quarter, total in product( + (date(1961, 12, 31), date(1962, 1, 31)), + (1962 * 4, 1962 * 4 + 1, 1962 * 4 + 2), + (5, 6, 19, 20), + ): + # A credited prior endpoint remains in the window, while an + # established current start still cannot occupy that quarter. + fixed = (*range(1957 * 4, 1957 * 4 + total - 1), credit_quarter) + _check_classification( + _declaration( + birth=date(1910, 2, 2), + onset=date(1962, 2, 15), + end=date(1962, 8, 31), + month=date(1968, 1, 1), + flags=flags, + fixed=fixed, + periods=(rule.DisabilityPeriod(date(1960, 1, 1), prior_end),), + ) + ) + + +@pytest.mark.parametrize("flags", FLAG_SETS) +def test_classification_oracle_six_qc_special_completions(flags): + for prior_unknown, total in product((False, True), (5, 6)): + prior = ( + () + if prior_unknown + else ( + rule.DisabilityPeriod( + date(2012, 4, 1), date(2021, 12, 31), special_insured=True + ), + ) + ) + _check_classification( + _declaration( + birth=date(1990, 2, 2), + onset=date(2022, 1, 15), + end=date(2022, 12, 31), + month=date(2023, 1, 1), + flags=flags, + periods=prior, + prior_unknown=prior_unknown, + counts=_counts(total, 2011), + ) + ) + _check_classification( + _declaration( + birth=date(1999, 2, 2), + onset=date(2022, 1, 15), + end=date(2022, 12, 31), + month=date(2023, 1, 1), + flags=flags, + counts=_counts(6, 2020), + ) + ) + + +@pytest.mark.parametrize("flags", FLAG_SETS) +def test_classification_oracle_unknown_years_straddle_start_horizon(flags): + for known in (1, 2): + _check_classification( + _declaration( + birth=date(1999, 2, 2), + onset=date(2022, 1, 15), + end=date(2022, 12, 31), + month=date(2023, 1, 1), + flags=flags, + counts=((2020, known),), + unknown_years=(2021, 2023), + ) + ) + + +@pytest.mark.parametrize("flag", FULLY_FLAGS) +def test_classification_oracle_historical_blindness_can_supply_two_priors( + flag, +): + case = _modern_case(29, 6, "recent", (flag,), False, "unknown") + assert _has_valid_filling(case) + _check_classification(case) + + +def test_classification_oracle_unknown_twenty_qcs_need_one_joint_start(): + case = _declaration( + birth=date(1931, 2, 2), + onset=date(1972, 4, 15), + end=date(1972, 12, 31), + month=date(1973, 1, 1), + prior_unknown=True, + fixed=(1962 * 4, *range(1967 * 4 + 1, 1972 * 4)), + ) + assert not _has_valid_filling(case) + _check_classification(case) + + +@pytest.mark.parametrize("flag", FULLY_FLAGS) +@pytest.mark.parametrize("total", (0, 5)) +def test_classification_oracle_unknown_history_cannot_remove_six_qc_floor( + flag, total +): + case = _modern_case(42, total, "recent", (flag,), False, "unknown") + assert not _has_valid_filling(case) + _check_classification(case) + + +def test_classification_oracle_alternate_needs_clear_start_before_1956(): + case = _declaration( + birth=date(1900, 2, 2), + onset=date(1955, 12, 15), + end=date(1956, 3, 31), + month=date(1968, 1, 1), + periods=(rule.DisabilityPeriod(date(1952, 7, 1), date(1955, 11, 30)),), + fixed=(*range(1938 * 4, 1941 * 4 + 2), *range(1951 * 4, 1952 * 4 + 2)), + ) + assert not _has_valid_filling(case) + _check_classification(case) + + +@pytest.mark.parametrize("flag", FULLY_FLAGS) +def test_classification_oracle_fully_flag_cannot_delay_an_insured_onset(flag): + case = _declaration( + birth=date(1910, 2, 2), + onset=date(1962, 2, 15), + end=date(1962, 8, 31), + month=date(1968, 1, 1), + flags=(flag,), + periods=(rule.DisabilityPeriod(date(1960, 1, 1), date(1962, 1, 31)),), + fixed=(*range(1957 * 4, 1961 * 4 + 3), 1962 * 4), + ) + assert not _has_valid_filling(case) + _check_classification(case) + + +@pytest.mark.parametrize("flag", FULLY_FLAGS) +def test_classification_oracle_blind_fully_flag_still_has_one_first_start( + flag, +): + case = _declaration( + birth=date(1960, 2, 2), + flags=(flag,), + blind=True, + periods=(rule.DisabilityPeriod(date(1999, 1, 1), date(2000, 1, 14)),), + ) + assert not _has_valid_filling(case) + _check_classification(case) + + +def test_classification_oracle_annual_placement_can_delay_first_insured_quarter(): + case = _declaration( + onset=date(2000, 2, 15), + periods=(rule.DisabilityPeriod(date(1999, 1, 1), date(2000, 1, 31)),), + counts=( + (1995, 4), + (1996, 4), + (1997, 4), + (1998, 4), + (1999, 3), + (2000, 1), + ), + ) + assert _has_valid_filling(case) + _check_classification(case) + + +@pytest.mark.parametrize("flags", FLAG_SETS) +def test_classification_oracle_annual_placement_boundary_lattice(flags): + for onset_count, prior_end, end in product( + (0, 1, 4), + (date(1999, 12, 31), date(2000, 1, 31)), + (date(2000, 2, 29), date(2000, 12, 31)), + ): + _check_classification( + _declaration( + onset=date(2000, 2, 15), + end=end, + flags=flags, + periods=(rule.DisabilityPeriod(date(1999, 1, 1), prior_end),), + counts=( + (1995, 4), + (1996, 4), + (1997, 4), + (1998, 4), + (1999, 3), + (2000, onset_count), + ), + ) + ) + + +@pytest.mark.parametrize("boundary", ("age31", "1952-start")) +@pytest.mark.parametrize("after", (False, True)) +def test_classification_oracle_adjacent_calendar_boundaries(boundary, after): + if boundary == "age31": + # RS00301.140 A: eligibility closes in the quarter attaining age 31. + # The known nonspecial prior preserves six QCs without opening + # the subsequent-special route on the other side of that line. + case = _declaration( + birth=date(1991, 2, 2), + onset=date(2022, 1, 15) if after else date(2021, 10, 15), + end=date(2022, 12, 31), + month=date(2023, 1, 1), + periods=( + rule.DisabilityPeriod(date(2013, 7, 1), date(2021, 9, 30)), + ), + counts=((2012, 4), (2013, 2)), + ) + expected = not after + else: + # RS00301.480 B.1 opens the alternate in 1952Q3. These historical + # endings imply recovery in Q2 versus Q3 under 404.321(b). + case = _declaration( + birth=date(1900, 2, 2), + onset=date(1952, 4, 15), + end=date(1952, 9, 30) if after else date(1952, 6, 30), + month=date(1968, 1, 1), + fixed=( + *range(1938 * 4, 1941 * 4 + 2), + *range(1951 * 4, 1952 * 4 + 2), + ), + ) + expected = after + assert _has_valid_filling(case) is expected + _check_classification(case) diff --git a/tests/test_track_b_insured_status_fix_round_11.py b/tests/test_track_b_insured_status_fix_round_11.py index 9143e2cdf..1c8bac6d1 100644 --- a/tests/test_track_b_insured_status_fix_round_11.py +++ b/tests/test_track_b_insured_status_fix_round_11.py @@ -204,11 +204,18 @@ def test_credit_route_keeps_refusal_even_with_complete_direct_envelope( @pytest.mark.parametrize("condition", FULLY_ROUTES) @pytest.mark.parametrize( - "exception,total", - [("blind", 3), ("unknown-prior", 3), ("unknown-prior", 6)], + "exception,total,last,possible", + [ + ("blind", 3, 2021, True), + ("unknown-prior", 3, 2021, False), + # 404.130(c)-(d): Rule III needs an earlier Rule II period. Credits + # first earned at age 40 can't supply its six QCs before age 31. + ("unknown-prior", 6, 2021, False), + ("unknown-prior", 6, 2003, True), + ], ) def test_fully_route_refuses_when_recent_credit_proof_does_not_apply( - condition, exception, total + condition, exception, total, last, possible ): person = _person(conditions=(condition,)) if exception == "blind": @@ -216,12 +223,11 @@ def test_fully_route_refuses_when_recent_credit_proof_does_not_apply( else: person = replace(person, prior_disability_periods_provenance=UNKNOWN) month = date(2023, 1, 1) - _assert_refusal( - person, - history(person, month, _counts(total)), - month, - _reason(condition), - ) + years = history(person, month, _counts(total, last=last)) + if not possible: + _assert_invalid(person, years, month) + return + _assert_refusal(person, years, month, _reason(condition)) @pytest.mark.parametrize("total", [3, 20]) diff --git a/tests/test_track_b_insured_status_fix_round_12.py b/tests/test_track_b_insured_status_fix_round_12.py index 5cf001850..ffab69762 100644 --- a/tests/test_track_b_insured_status_fix_round_12.py +++ b/tests/test_track_b_insured_status_fix_round_12.py @@ -439,8 +439,13 @@ def test_empty_windows_keep_fully_route_blindness_and_unknown_prior_bypasses( person = replace(person, statutory_blindness=True) else: person = replace(person, prior_disability_periods_provenance=UNKNOWN) - years = history(person, date(2001, 1, 1)) + # Missing prior history can move a window, but cannot remove its floor. + # Six old credits keep this fixture about the empty recent windows. + counts = {1980: 4, 1981: 2} if exception == "unknown-prior" else {} + years = history(person, date(2001, 1, 1), counts) _refusal(person, years, _reason(condition)) + if exception == "unknown-prior": + _invalid(person, history(person, date(2001, 1, 1))) @pytest.mark.parametrize("condition", FULLY_ROUTES) diff --git a/tests/test_track_b_insured_status_fix_round_13.py b/tests/test_track_b_insured_status_fix_round_13.py new file mode 100644 index 000000000..7e5f1c861 --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_13.py @@ -0,0 +1,317 @@ +"""Statutory conformance: every route uses one feasible insured start. + +Invented declarations only; no population, behavioral, or forecast claim. +The zero-credit blind and credit-adding cases, six-credit boundary, +clear alternate candidate, credited endpoint, and undeclared-period cases +pin unchanged behavior. The other cases expose the round-thirteen defects. +""" + +from dataclasses import replace +from datetime import date +from fractions import Fraction + +import pytest + +from populace_dynamics.track_b import insured_status as i +from populace_dynamics.track_b.gross_benefits import count_family_outcomes +from tests.test_track_b_insured_status import history + +OBSERVED = i.EarningsProvenance.OBSERVED +UNKNOWN = i.EarningsProvenance.UNKNOWN +WEIGHT = Fraction(11, 5) +FULLY_ROUTES = ( + i.CoverageCondition.DEEMED_FULLY_INSURED, + i.CoverageCondition.TRANSITIONAL_INSURED, + i.CoverageCondition.EARNED_BASIS, + i.CoverageCondition.SIMPLIFIED_PRE1951, +) +CREDIT_ROUTES = ( + i.CoverageCondition.MILITARY_CREDITS, + i.CoverageCondition.MEDICARE_GOVERNMENT_EMPLOYMENT, +) +RAW_ROUTES = ( + i.CoverageCondition.RAILROAD_CREDITS, + i.CoverageCondition.FISCAL_TAXABLE_YEAR, + i.CoverageCondition.SHORT_TAXABLE_YEAR, +) + + +def _person(**kwargs): + facts = { + "disability_onset": date(2000, 1, 15), + "current_disability_period_established": True, + "current_disability_period_provenance": OBSERVED, + "current_disability_period_end": date(2000, 12, 31), + "current_disability_period_end_provenance": OBSERVED, + "prior_disability_periods_provenance": UNKNOWN, + "conditions": (FULLY_ROUTES[0],), + "sspa211_applies": False, + "sspa211_provenance": OBSERVED, + } + facts.update(kwargs) + return i.Person(date(1960, 2, 2), **facts) + + +def _evaluate(person, years, month, **kwargs): + return i.evaluate_insured_status( + "round-thirteen-common-start", + WEIGHT, + lambda: i.insured_status( + person, years, month, test=i.InsuredTest.FULLY, **kwargs + ), + ) + + +def _invalid(person, years, month, **kwargs): + rows = [] + with pytest.raises(i.InvalidFamilyInput, match="no possible insured"): + rows.append(_evaluate(person, years, month, **kwargs)) + counts = count_family_outcomes(rows) + assert counts.rows == counts.unsupported_rows == 0 + assert counts.weight == counts.unsupported_weight == 0 + + +def _refusal(person, years, month, reason, **kwargs): + row = _evaluate(person, years, month, **kwargs) + assert row.result is None + assert row.unsupported.reason is reason + counts = count_family_outcomes((row,)) + assert counts.rows == counts.unsupported_rows == 1 + assert counts.weight == counts.unsupported_weight == WEIGHT + return row + + +def _alternate(*, onset, prior_end, end=date(1956, 3, 31), endpoint=False): + person = i.Person( + date(1900, 2, 2), + sex=i.Sex.FEMALE, + disability_onset=onset, + current_disability_period_established=True, + current_disability_period_provenance=OBSERVED, + current_disability_period_end=end, + current_disability_period_end_provenance=OBSERVED, + prior_disability_periods=( + i.DisabilityPeriod(date(1952, 7, 1), prior_end), + ), + prior_disability_periods_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + month = date(1968, 1, 1) + credited = set(range(1938 * 4, 1938 * 4 + 14)) + credited.update(range(1951 * 4, 1951 * 4 + 6)) + if endpoint: + credited.add(prior_end.year * 4 + (prior_end.month - 1) // 3) + years = history(person, month) + for year in years: + if year < 1978: + years[year] = i.CoverageYear( + OBSERVED, + qc_quarters=tuple( + year * 4 + quarter in credited for quarter in range(4) + ), + ) + return person, years, month + + +@pytest.mark.parametrize("coverage_end", [None, date(2000, 12, 1)]) +def test_review_unknown_prior_cannot_remove_six_qc_floor(coverage_end): + """Sol's first case, on direct and coverage-end public paths.""" + person = _person() + month = date(2001, 1, 1) + _invalid( + person, + history(person, month, end=coverage_end), + month, + coverage_end_month=coverage_end, + ) + + +@pytest.mark.parametrize("coverage_end", [None, date(1956, 3, 1)]) +@pytest.mark.parametrize( + "end", [date(1956, 3, 31), date(1956, 12, 31), date(1959, 12, 31)] +) +def test_review_alternate_start_must_clear_same_prior_overlap( + coverage_end, end +): + """Sol's second case and its two longer-period controls.""" + person, years, month = _alternate( + onset=date(1955, 12, 15), prior_end=date(1955, 11, 30), end=end + ) + if coverage_end: + years = { + year: row + for year, row in years.items() + if year <= coverage_end.year + } + _invalid(person, years, month, coverage_end_month=coverage_end) + + +@pytest.mark.parametrize("condition", FULLY_ROUTES) +@pytest.mark.parametrize( + "by_horizon,after_horizon", + [(5, 0), (6, 0), (5, 1)], + ids=["five", "six", "sixth-one-quarter-late"], +) +def test_unknown_prior_fully_route_floor_uses_horizon_credits( + condition, by_horizon, after_horizon +): + person = _person(conditions=(condition,)) + month = date(2001, 1, 1) + years = history( + person, + month, + {1980: 4, 1981: by_horizon - 4, 2001: after_horizon}, + ) + # Early QCs permit an under-31 prior start in an UNKNOWN completion; + # the six-QC control therefore has one joint special-prior filling. + # End 12/2000 permits a latest recovery/start in 10/2000 (2000Q4). + # The sole 2001 QC is therefore one quarter after every possible start. + if by_horizon < 6: + _invalid(person, years, month) + else: + _refusal( + person, years, month, i.InsuredUnsupportedReason[condition.name] + ) + + +@pytest.mark.parametrize("condition", FULLY_ROUTES) +def test_twenty_future_credits_cannot_repair_zero_by_start_horizon(condition): + """The review's temporal-floor probe cannot use lifetime totals.""" + person = _person(conditions=(condition,)) + month = date(2007, 1, 1) + years = history(person, month, {year: 4 for year in range(2002, 2007)}) + _invalid(person, years, month) + + +@pytest.mark.parametrize("condition", FULLY_ROUTES) +def test_blind_fully_route_with_zero_credits_keeps_named_refusal(condition): + """Unchanged: 404.130(e) dispenses with the recent-credit test.""" + person = _person(conditions=(condition,), statutory_blindness=True) + month = date(2001, 1, 1) + _refusal( + person, + history(person, month), + month, + i.InsuredUnsupportedReason[condition.name], + ) + + +def test_blind_without_fully_route_still_needs_six_own_credits(): + """Unchanged: blindness alone does not supply fully insured status.""" + person = _person(conditions=(), statutory_blindness=True) + month = date(2001, 1, 1) + _invalid(person, history(person, month, {1998: 4, 1999: 1}), month) + + +@pytest.mark.parametrize("condition", (None, *CREDIT_ROUTES, *RAW_ROUTES)) +def test_foreign_and_credit_adding_routes_precede_floor(condition): + """Unchanged: these unresolved routes can add undeclared QCs.""" + person = _person(conditions=(condition,) if condition else ()) + month = date(2001, 1, 1) + years = history(person, month) + if condition in RAW_ROUTES: + years[2000] = i.CoverageYear(OBSERVED, wages=Fraction(0)) + kwargs = {} if condition else {"totalization_credits": ("invented",)} + _refusal( + person, + years, + month, + ( + i.InsuredUnsupportedReason[condition.name] + if condition + else i.InsuredUnsupportedReason.TOTALIZATION + ), + **kwargs, + ) + + +@pytest.mark.parametrize("endpoint", [False, True]) +def test_alternate_uses_one_clear_candidate_after_prior_ending_quarter( + endpoint, +): + """Unchanged: onset Q3 overlaps, but the sole clear Q4 may start.""" + person, years, month = _alternate( + onset=date(1955, 9, 15), + prior_end=date(1955, 8, 31), + endpoint=endpoint, + ) + _refusal( + person, + years, + month, + i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956, + ) + + +@pytest.mark.parametrize("end", [date(1956, 3, 31), date(1959, 12, 31)]) +def test_post1955_clear_start_cannot_replace_overlapped_alternate(end): + person, years, month = _alternate( + onset=date(1955, 12, 15), prior_end=date(1955, 11, 30), end=end + ) + _invalid(person, years, month) + + +@pytest.mark.parametrize( + "established", [False, None], ids=["false", "unknown"] +) +def test_unestablished_alternate_keeps_prior_treatment(established): + """Unchanged: candidate nonoverlap belongs to established periods.""" + person, years, month = _alternate( + onset=date(1955, 12, 15), prior_end=date(1955, 11, 30) + ) + person = replace( + person, + current_disability_period_established=established, + current_disability_period_provenance=( + UNKNOWN if established is None else OBSERVED + ), + current_disability_period_end=None, + current_disability_period_end_provenance=UNKNOWN, + ) + row = i.evaluate_insured_status( + "round-thirteen-unestablished-control", + WEIGHT, + lambda: i.insured_status( + person, years, month, test=i.InsuredTest.DISABILITY + ), + ) + assert row.result is None + assert ( + row.unsupported.reason + is i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956 + ) + counts = count_family_outcomes((row,)) + assert counts.rows == counts.unsupported_rows == 1 + assert counts.weight == counts.unsupported_weight == WEIGHT + + +def test_disability_witness_uses_the_legal_annual_start_filling(): + """The same placement must supply the start and disability witness.""" + person = _person( + disability_onset=date(2000, 2, 15), + conditions=(), + prior_disability_periods=( + i.DisabilityPeriod(date(1999, 1, 1), date(2000, 1, 31)), + ), + prior_disability_periods_provenance=OBSERVED, + ) + month = date(2001, 1, 1) + years = history( + person, + month, + {1995: 4, 1996: 4, 1997: 4, 1998: 4, 1999: 3, 2000: 1}, + ) + row = i.evaluate_insured_status( + "round-thirteen-disability-start-filling", + WEIGHT, + lambda: i.insured_status( + person, years, month, test=i.InsuredTest.DISABILITY + ), + ) + assert row.unsupported is None + assert row.result.current_disability_period_start == date(2000, 4, 1) + assert row.result.disability.qualifying_quarter == date(2000, 4, 1) + counts = count_family_outcomes((row,)) + assert counts.rows == 1 and counts.unsupported_rows == 0 + assert counts.weight == WEIGHT and counts.unsupported_weight == 0 diff --git a/tests/tier_counts.json b/tests/tier_counts.json index fe674b50e..ab0dc861c 100644 --- a/tests/tier_counts.json +++ b/tests/tier_counts.json @@ -1,7 +1,7 @@ { "schema_version": 1, "counts": { - "unit": 20971, + "unit": 21140, "artifact": 4271, "integration_psid": 1471, "reproduction_legacy": 520, From 5ad31723565d503c6579912432fbf36e229d80c0 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sat, 31 Oct 2026 18:53:58 -0400 Subject: [PATCH 19/46] State why a flag can't delay the first insured quarter (#562 round 13) The rule doesn't test when a fully-route flag's status began, so the first-start reasoning needs a premise the note left unstated. Prior periods end before onset, so overlap reaches only the onset quarter, and that prior's own insured status puts fully insured status in place before onset. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index 3ddcb4301..9b3a5e7a4 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -1658,7 +1658,15 @@ added UNKNOWN-history oracle lattice. For known priors, 404.321(a) fixes onset when insured then, otherwise the first insured quarter. A fully-route flag presumes that prerequisite and -changes nothing else. The recent scan now holds one complete annual +changes nothing else. The rule doesn't test when a flag's status began, and +this reasoning doesn't need that date. Prior periods end before onset, so +overlap reaches only the onset quarter, through a prior that ends there. +That prior was itself insured, and 404.130(a) makes fully insured status +part of every rule, so the person met it when the prior began. Fully +insured status compares QCs with a requirement. QCs don't fall, and the +elapsed-year count skips every year any part of which falls in the prior, +so the status still holds in the onset quarter. +The recent scan now holds one complete annual placement and prior treatment fixed before selecting that first quarter; a later clear quarter cannot repair an overlapping first quarter. A blind fully-route declaration is insured at onset and needs a clear onset From 36c5c2003c66f29b84891d4b2a7b203e0adc33ca Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sat, 31 Oct 2026 20:12:49 -0400 Subject: [PATCH 20/46] Keep lawful insured rows and refuse starts a filling can't settle (#562 round 14) Sol's tenth review found three mediums, and all three reproduce. In each, the rule rejected or settled something it couldn't prove. The rule now takes one direction: where it can't show that every filling is invalid, it refuses by name. A loose refusal keeps a row a stricter proof could drop, and a false rejection loses a lawful row and its weight. - Past blindness. The earliest-prior emptiness proof tested a prior with the person's current nonblindness. statutory_blindness=False says nothing about the past, and a blind prior needs only fully insured status under 404.130(e). - A flag's start. Round 13 treated the first recent-only quarter as the first insured quarter, so a flag could invalidate a declaration that computes without it. The rule doesn't know when a flag's status began. An overlapping quarter now fixes the start only when the person is ordinarily insured there, for one filling and treatment. Blindness uses the same scan. The design note's persistence argument held with the prior used and failed with it disregarded, so this commit replaces it. - Annual placement. The retry took the first filling that worked, which set a status by iteration order. RS 00301.230 assigns QCs "to the quarters most advantageous to the NH", and carrying every start through every status isn't supported. The search now only proves possibility, and a clear start in that corner refuses disability_boundary_assignments_unsupported. Later input errors still come first. The classification oracle passed the flag defect because it assumed the same thing: a flag made a person fully insured in every quarter. It now treats the flag's first quarter as a free fact and adds blind priors for people with no flag. A new status oracle checks returned FULLY, CURRENTLY and DISABILITY against the most favorable lawful filling in plain arithmetic, which the old oracle excluded. Round 13's overlap corner was the only disagreement it found. Round 13's oracle also declared a tier marker that conftest assigns, which failed the tier-policy test in CI. This commit removes that declaration here and in the new module, and it sorts boundary candidates so tied witnesses don't depend on enumeration order. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 216 +++-- .../track_b_insured_status_mutations.json | 364 ++++++++- .../track_b/insured_status.py | 138 ++-- tests/README-tiers.md | 4 +- ..._b_insured_status_classification_oracle.py | 380 ++++++--- ...est_track_b_insured_status_fix_round_13.py | 14 +- ...est_track_b_insured_status_fix_round_14.py | 773 ++++++++++++++++++ ...st_track_b_insured_status_status_oracle.py | 272 ++++++ tests/tier_counts.json | 2 +- 9 files changed, 1939 insertions(+), 224 deletions(-) create mode 100644 tests/test_track_b_insured_status_fix_round_14.py create mode 100644 tests/test_track_b_insured_status_status_oracle.py diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index 9b3a5e7a4..c26f553d5 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -253,15 +253,18 @@ that floor; RS .480 also requires twenty. Blindness with a fully-route flag alone bypasses this proof because 404.130(e) has no recent-credit test and the flag presumes its fully insured prerequisite. Blindness without that flag still needs six ordinary fully insured QCs. -With known prior history and no blindness, a fully-route flag also needs a +With known prior history, a nonblind fully-route flag also needs a possible recent rule in a nonoverlapping starting quarter from onset through the immutable horizon, or a possible automatic pre1956 alternate. The recent scan uses the same annual assignment, fixed all-period use/disregard treatment, and special-window rules as the ordinary witness, relaxing only its fully insured prerequisite (404.130(a)–(d), (f)). If maximum feasible credits cannot satisfy any such recent rule and the alternate is unavailable, no -lower-credit filling can establish the period. A fully-route flag changes -neither constraint. A complexity refusal during this scan preserves +lower-credit filling can establish the period. Only ordinary insurance +without a flag fixes an overlapping first quarter for one filling and +treatment. A recent-only quarter does not establish when the flag begins. +Blind fully-route declarations have no recent requirement and retain the +same free flag-start fact. A complexity refusal during this scan preserves possibility so that the flag retains its own named refusal. The horizon six-QC floor precedes the automatic alternate. The pre1956 @@ -312,8 +315,12 @@ waiting-period exceptions. The interface does not adjudicate those administrative facts for an already declared period; it imposes no five-month validation on current or supplied prior periods. -The scan uses maximum feasible QCs for unknown years and does not try to -prove administrative feasibility. Any possible specialist starting route +The scan uses maximum feasible QCs for unknown years and tests each +earliest prior as blind, regardless of current blindness (404.130(e); +RS 00301.150). A blind prior needs only fully insured status, so failing a +nonblind recent test cannot prove that prior history empty. The alternate +check before that witness is unchanged. The scan does not try to prove +administrative feasibility. Any possible specialist starting route also prevents an empty-history impossibility proof. If no quarter or route survives, empty prior history is the only remaining case for current establishment validation; only impossibility there permits an input error @@ -801,7 +808,7 @@ to a statutory sentence that does not state it. | I5. A supplied `special_insured` prior period begins before the age-31 attainment quarter. | B404.130(d)(1): a prior period "began before age 31" and the worker "were only insured under paragraph (c)"; (c)(1) requires age 31 not yet attained. A216(i)(3)(B)(iii) expressly uses "before the quarter" of age 31. The flag declares this particular adjudicated young-worker route, not every possible special credit regime. | | I6. An alien worker's actual pre2004 SSN assignment conflicts with declared SSPA applicability; birth on/after January 1, 2004 conflicts with declared exemption. Both never-assigned and an assigned SSN, or assignment before birth, remain invalid. A worker born before 2004 may pair a post2003 assignment or never-assigned status with an adjudicated exemption. | RS .102 B.1 says an alien assigned an SSN before 2004 "is exempt", including a nonwork SSN. B.3.b says, "If an alien worker could have legitimately been assigned an SSN before 1/1/2004, the worker is exempt from the requirements of section 211 of the SSPA." Its wrong-number SS-5 scenario issued another person's number "instead of assigning the alien worker their own SSN". Thus observed or convention-filled exemption overrides either later-assignment or never-assigned presumptions when legitimate pre2004 assignment was possible. Birth on/after January 1, 2004 rules out that exception independently of the assignment record. B.4.b's worker without an SSN "is nevertheless considered to meet the work SSN requirement" when work-authorized; meeting that requirement alone supplies no exemption. | | I7. Explicit quarterly QCs or positive quarterly wages cannot occur before birth, after the query/coverage-end quarter, or after the death quarter. Every required coverage year is declared exactly once through the earliest query, exit, or death year. | A213(a)(2)(B)(i), (v): "no quarter after the quarter in which an individual dies" and "no quarter shall be counted ... prior to the beginning of such quarter"; B404.146(a)-(b) agree. Birth and supplied-record exit caps, complete years, and no implicit zeros are interface premises. Annual counts are capped rather than dated after exit. Specialist earned-basis or additional-credit declarations remain refusals and do not reinterpret an explicit ordinary covered-quarter declaration. | -| I8. A declared current establishment is invalid only after the shared possibility check excludes every route and every feasible prior/earnings filling. One ordinary filling must satisfy its insured start, recovery or administrative end, continuity, and overlap constraints together. | C320(b)(2) requires insured disability "in the calendar quarter in which you became disabled, or in a later calendar quarter"; C321(a) chooses the first such quarter. B404.130(a) supplies four ordinary rules and RS .480 supplies the alternate historical rule. The start horizon uses an inferred recovery month when I14 permits one, otherwise the declared end, together with continuity/query/death/FRA caps. Maximum credits establish only monotone insurance by that fixed horizon. A derived prior-quarter overlap requires a single lower-credit or enumerated filling whose first start also clears that overlap. An ordinary or alternate witness after the horizon cannot supply possibility. Foreign credits and the flag classes determine which credit-count proofs apply, in the refusal order above, before any alternate or boundary enumeration. The alternate's 20/40 exclusion instead uses U10's earliest date shared by every completion; a later witness cannot prove impossibility under every defensible reading of RS .480 A. | +| I8. A declared current establishment is invalid only after the shared possibility check excludes every route and every feasible prior/earnings filling. One ordinary filling must satisfy its insured start, recovery or administrative end, continuity, and overlap constraints together. | C320(b)(2) requires insured disability "in the calendar quarter in which you became disabled, or in a later calendar quarter"; C321(a) chooses the first such quarter. B404.130(a) supplies four ordinary rules and RS .480 supplies the alternate historical rule. The start horizon uses an inferred recovery month when I14 permits one, otherwise the declared end, together with continuity/query/death/FRA caps. Maximum credits establish only monotone insurance by that fixed horizon. A derived prior-quarter overlap requires a single lower-credit or enumerated filling whose first start also clears that overlap. A clear ordinary start found only through placement or treatment search establishes possibility and retains a named refusal; it does not select a status witness. An ordinary or alternate witness after the horizon cannot supply possibility. Foreign credits and the flag classes determine which credit-count proofs apply, in the refusal order above, before any alternate or boundary enumeration. The alternate's 20/40 exclusion instead uses U10's earliest date shared by every completion; a later witness cannot prove impossibility under every defensible reading of RS .480 A. | | I9. Except for blindness with a fully-route flag, fewer than six maximum feasible QCs by the immutable start horizon proves current establishment impossible after foreign credits, credit-route flags, and unresolved raw-earnings flags have preserved their possible routes. | B404.110(b)(1): "You need at least 6 QCs but not more than 40 QCs"; B404.130(a): "you must be fully insured". The flag table supplies each exception's captured premise. A record composed entirely of direct final QC declarations (`qc_count` or `qc_quarters`) and UNKNOWN years fixes or bounds all admissible final credits from RR compensation and fiscal/short taxable-year allocation. This is the direct-credit input contract, not a claim that ordinary RSDI credits exhaust freeze-only military credits: B404.133 expressly supplies the latter, so `MILITARY_CREDITS` remains a separate credit route even with direct rows. Any raw row leaves the raw-earnings route unresolved. Period exclusions alone cannot add ordinary QCs. RS .480 A separately requires 20 QCs and the explicit `DISABILITY_BEFORE_1956` flag adds no route beyond the automatic alternate, so it cannot rescue a below-six declaration. Fully-route flags replace only the fully insured prerequisite; nonblind recent rules retain the universal horizon floor in I17, even under UNKNOWN prior history. Blindness with a fully-route flag bypasses that floor under 404.130(e). No ordinary floor applies to the unmodeled foreign-credit route (U11). | | I10. The supported calendar, mandatory historical sex, and explicit establishment declaration must be supplied: birth years 1870–9900, query years through 9990, sex for births before January 2, 1913, and establishment provenance whenever onset is present. | These are interface-domain requirements. B404.110(b)(2) and .132 apply different historical male/female endpoints; B404.110(c) excludes only a period "we established for you". Missing facts are not inferred. Calendar limits reserve space for date arithmetic and assert no legal incapacity outside the implementation domain; alternative credit routes cannot supply missing declared facts. | | I11. A continues-through observation requires established disability, cannot precede medical onset or the first feasible insured start, cannot exceed the pre-FRA or death boundary, and cannot follow a declared administrative end. | C320(b)(2) and C321(a) require the insured start; A216(i)(2)(D) and C321(c) bound the period's end. A declaration that a period was in force on a date requires that date to lie within one possible period. This is a dated observation, not an asserted ending; a date later than the query is allowed. Provenance and convention identifiers follow the existing fact schema. | @@ -809,17 +816,17 @@ to a statutory sentence that does not state it. | I13. If no starting quarter from onset through the immutable horizon clears all supplied prior-period quarters, current establishment is impossible independently of credit fillings, their count, or a specialist route. | C320(b)(2) and C321(a) require an insured beginning within that interval; I4's nonoverlapping-quarter representation applies to that same beginning. A credit route cannot move a candidate outside the fixed interval or remove a supplied prior quarter. This fixed contradiction is checked before specialist possibility and filling enumeration; it does not treat UNKNOWN prior history as supplied empty history. | | I14. A declared recovery-only historical end implies a recovery month two months earlier; recovery before the onset month or a derived start after that month is invalid. | C321(b) ends the period on "the last day of the second month following the month in which your disability ended". C320(b)(2) and B404.131(a) require an insured quarter in which the worker was disabled, so an administrative grace month cannot supply a new disabled quarter. The helper returns no recovery inference for an end on/after February 1, 1981, in/after the month preceding FRA, or in/after the death month. These carve-outs preserve the existing validity horizon and make no claim about paragraph (c) recovery or administrative ending rules. | -| I15. With known prior history, no blindness, no foreign credits, no credit-route flag, and no raw-earnings flag outside a complete direct-QC envelope, fewer maximum feasible lifetime QCs than the lowest remaining recent-rule requirement proves establishment impossible before fully-route refusals or coverage enumeration. | B404.130(a) requires a recent rule "and you must be fully insured". The flag table's fully-route rules cannot change the independent recent-credit requirement. B404.130(b) needs 20 QCs; (c)–(d) permit the special half-elapsed-quarter rule with six-QC floor and 20-QC ceiling; RS .480 A also needs 20. At the earliest candidate start, remove every prior-period quarter from special elapsed time, including credited endpoints. Every actual use/disregard witness has at least those elapsed quarters, and later starts cannot reduce them. Taking the smallest applicable requirement therefore cannot exceed any true route minimum. Ignoring the fully insured prerequisite and window availability only relaxes the bound. Blindness (B404.130(e)) needs only fully insured status, and UNKNOWN prior history could remove further quarters; both disable this stronger numerical proof and I16's recent scan, but UNKNOWN prior history does not disable I17's six-QC horizon floor. The minimum remains ahead of every boundary enumeration, including the recent scan. | -| I16. With known prior history, no blindness, and no route adding credits outside the declared envelope, a fully-route flag cannot establish a current period unless some nonoverlapping candidate quarter meets a recent rule under maximum feasible credits or the automatic pre1956 alternate remains possible. | B404.130(a) requires one rule "and you must be fully insured"; (b) requires 20 QCs in 40 quarters; (c) and (d) supply the under31 and subsequent-special recent alternatives. C320(b)(2) permits the onset quarter or a later disabled quarter, and C321(a) selects the first qualifying quarter. The scan includes onset and horizon. For each complete annual placement and fixed prior treatment, its first insured quarter must clear I13's overlap predicate. A later clear quarter cannot repair an earlier insured overlap. With UNKNOWN earnings, lower fillings are included; at most 4,096 placements/fillings are enumerated. When every candidate is already clear, the existing upper-credit scan suffices. It retains B404.130(f)'s favorable all-period use or disregard and annual assignment, and relaxes only the fully insured prerequisite. Upper credits bound the recent test when no start can overlap. In the overlap corner, complete placements and unresolved lower fillings are tested together, because removing or moving an early QC can delay the first insured start. An open RS .480 route remains an independent possibility for a fully-route flag. A complexity refusal is not impossibility and preserves the flag's own named refusal. The scan tests no flag-specific condition. | +| I15. With known prior history, no blindness, no foreign credits, no credit-route flag, and no raw-earnings flag outside a complete direct-QC envelope, fewer maximum feasible lifetime QCs than the lowest remaining recent-rule requirement proves establishment impossible before fully-route refusals or coverage enumeration. | B404.130(a) requires a recent rule "and you must be fully insured". The flag table's fully-route rules cannot change the independent recent-credit requirement. B404.130(b) needs 20 QCs; (c)–(d) permit the special half-elapsed-quarter rule with six-QC floor and 20-QC ceiling; RS .480 A also needs 20. At the earliest candidate start, remove every prior-period quarter from special elapsed time, including credited endpoints. Every actual use/disregard witness has at least those elapsed quarters, and later starts cannot reduce them. Taking the smallest applicable requirement therefore cannot exceed any true route minimum. Ignoring the fully insured prerequisite and window availability only relaxes the bound. Blindness (B404.130(e)) needs only fully insured status, and UNKNOWN prior history could remove further quarters; both disable this stronger numerical proof. Blindness removes I16's recent-credit requirement; UNKNOWN prior history skips its known-history scan, but does not disable I17's six-QC horizon floor. The minimum remains ahead of every boundary enumeration, including the recent scan. | +| I16. With known prior history and no route adding credits outside the declared envelope, a fully-route flag needs a possible clear first insured start or the automatic pre1956 alternate. Nonblindness retains the recent rule; blindness has none. | B404.130(a) requires one rule "and you must be fully insured"; (b) requires 20 QCs in 40 quarters; (c) and (d) supply the under31 and subsequent-special recent alternatives. C320(b)(2) permits the onset quarter or a later disabled quarter, and C321(a) selects the first qualifying quarter. The scan includes onset and horizon. For each complete annual placement and fixed prior treatment, only ordinary insurance without a flag fixes an overlapping first quarter. Recent-only insurance does not date the flag's fully insured status; the first flagged start may be later and clear. Blindness similarly leaves the flag's start unknown, including with zero QCs. Ordinary insurance in the overlapping quarter under every filling and treatment still proves impossibility. With UNKNOWN earnings, lower fillings are included; at most 4,096 placements/fillings are enumerated. When every candidate is already clear, the existing upper-credit scan suffices. It retains B404.130(f)'s favorable all-period use or disregard and annual assignment, and relaxes only the fully insured prerequisite. Upper credits bound the recent test when no start can overlap. In the overlap corner, complete placements and unresolved lower fillings are tested together, because removing or moving an early QC can delay the first insured start. An open RS .480 route remains an independent possibility for a fully-route flag. A complexity refusal is not impossibility and preserves the flag's own named refusal. The scan tests no flag-specific condition. | | I17. Every declared-envelope nonblind establishment route has at least six QCs feasible by its immutable start horizon, including fully-route flags and UNKNOWN prior histories. Blindness without a fully-route flag retains the ordinary fully insured floor. | B404.130(b)(2) requires "at least 20 QCs"; (c)(3)(ii) and (d)(2)(ii) require "at least 6 QCs in the 12-quarter period". Paragraph (f) changes the counted window, never this floor. Only (e) removes the recent requirement, retaining fully insured status. RS .480 A also needs twenty QCs by its start. UNKNOWN prior history may remove elapsed quarters or open a subsequent-special route, but cannot remove this minimum. Credits after the horizon cannot satisfy it. Foreign and unmodeled credit routes remain outside the declared envelope and precede the proof. | -| I18. An established pre1956 alternate uses one start quarter satisfying prior-period nonoverlap, the immutable horizon and the historical date limit together. | C320(b)(2), C321(a), I13 and RS .480 B.1 require an eligible insured start no later than 12/31/55. A later nonoverlapping ordinary candidate cannot validate an overlapping alternate candidate. This check does not change the alternate continuous clock, credited endpoint treatment, lower-credit exclusion scan, or false/UNKNOWN establishment. | +| I18. An established pre1956 alternate uses one start quarter satisfying prior-period nonoverlap, the immutable horizon and the historical date limit together. | C320(b)(2), C321(a), I13 and RS .480 B.1 require an eligible insured start no later than 12/31/55. A later nonoverlapping ordinary candidate cannot validate an overlapping alternate candidate. This check does not change the alternate continuous clock, credited endpoint treatment, lower-credit exclusion scan, or false/UNKNOWN establishment. Unlike a recent-only flagged candidate, an alternate candidate must itself satisfy every starting condition together; the flag-start correction does not move this candidate. | | ID and UNKNOWN collapse | Captured text and alternative-route defense | | --- | --- | | U1. UNKNOWN prior history can collapse to empty solely for impossibility validation when no earliest prior period could start insured, on/after birth, before current onset and the FRA end. | C320(b)(2) and C321(a) require an insured beginning without a still-earlier period. A216(i)(2)(A) permits "five full calendar months' duration or" DIB entitlement "for one or more months". The scan therefore admits a one-month period and maximum feasible earnings. Any possible ordinary or specialist starting route stops the proof. It establishes no observed empty-history fact. | | U2. UNKNOWN current establishment needs no new-period alternative if there is no medical onset or onset is at/after the statutory latest starting month. | A216(i)(2)(A)-(D) and C321 prohibit a period without disability or a nonempty pre-FRA interval. This removes an impossible new-period alternative only; it does not remove UNKNOWN prior history or an existing period's UNKNOWN administrative end. | | U3. With unknown prior/current periods, true ordinary FULLY and CURRENTLY status under favorable all-period disregard decides true. A DISABILITY witness must also survive any current-establishment completion that ends the disability before that witness. | C320(a): "If benefits ... would be denied or reduced because of a period of disability, the period of disability will not be taken into consideration." B404.130(f) also permits counting all prior quarters if favorable. RS .120 requires all periods used or all disregarded; selective exclusions are not assumed. Specialist credit regimes are refused first. | -| U4. With unknown periods, fewer than six maximum QCs feasible by the immutable horizon proves establishment impossible after routes adding undeclared credits are excluded, except for blindness with a fully-route flag; it supplies no foreign-credit impossibility proof. | B404.110(b)(1) and B404.130(a) supply the ordinary six-QC prerequisite. U3's disregard cannot manufacture credits. UNKNOWN prior history disables both I15 and I16; it can preserve a fully-route refusal with empty recent windows only after the universal six-QC horizon floor clears (I17). Foreign credits, credit-route flags, and raw-earnings flags outside a complete direct envelope also preserve named refusals. The direct-envelope contract and declared pre1956 alternate still obey I9; that alternate flag adds no route beyond B4. Blindness alone supplies no credits and does not replace the ordinary fully insured prerequisite. | +| U4. With unknown periods, fewer than six maximum QCs feasible by the immutable horizon proves establishment impossible after routes adding undeclared credits are excluded, except for blindness with a fully-route flag; it supplies no foreign-credit impossibility proof. | B404.110(b)(1) and B404.130(a) supply the ordinary six-QC prerequisite. U3's disregard cannot manufacture credits. UNKNOWN prior history disables both I15 and I16; current nonblindness cannot exclude a past blind prior. The separate emptiness proof tests the earliest prior as blind, and proves emptiness only if no earlier quarter can supply fully insured status or the alternate. It can preserve a fully-route refusal with empty recent windows only after the universal six-QC horizon floor clears (I17). Foreign credits, credit-route flags, and raw-earnings flags outside a complete direct envelope also preserve named refusals. The direct-envelope contract and declared pre1956 alternate still obey I9; that alternate flag adds no route beyond B4. Blindness alone supplies no credits and does not replace the ordinary fully insured prerequisite. | | U5. UNKNOWN earnings decide a requested Boolean only if all lower/upper ordinary earnings witnesses agree, under the permitted fixed-period/all-period treatments; an uncertain established start refuses only after at least one feasible filling survives. | B404.143 credits one QC for each increment, maximum four; B404.130 and .146 supply assignment/exclusion rules. Adding ordinary QCs cannot invalidate a fixed treatment. A derived start cannot be silently held fixed when the completion changes it. If a lower or upper representative cannot construct the declared period, but another single filling meets its end, continuity, and prior-overlap constraints, the public result is `unknown_earnings_years_decide_status`. If no ordinary filling can qualify by the declared end and all independent routes are impossible, it is an input error and creates no row. A deferred raw-conversion row uses temporary unknown fillings only for possibility, then retains its conversion refusal. Specialist possibilities and administrative-end candidates are considered separately. | | U6. UNKNOWN administrative end decides a status only when every end-quarter candidate from start through query/cap, plus permitted continuation, agrees, after applying any continuity lower bound. | A216(i)(2)(D) uses "whichever ... is the earlier"; C321(c)(3) includes "the last month for which you received benefits" after substantial gainful activity. Medical continuity cannot exclude early ends; a dated administrative continuity observation can. FRA/death caps limit the latest candidate and do not turn the unknown into a fact. Both ending and prior-history unknown facts remain disclosed when both are missing; UNKNOWN prior history uses the universal envelopes rather than inventing a derived current period to enumerate. The unchanged completion enumeration can include early endings rejected by I14 if declared concretely. Agreement across that larger set still implies agreement across every valid completion, while disagreement can preserve an extra refusal. An actual supplied end keeps its declared-date semantics; known ending provenance requires an ending date. | | U7. UNKNOWN SSPA applicability preserves an ordinary QC-only false status, but never a QC-only true status. | RS .102 B.2 says the worker "must meet one of the following additional requirements" and may fail "even if" the QC requirement is met. Applicability can remove ordinary insurance and cannot supply missing QCs. Known applicability retains adjudication refusal; any separate specialist path is refused first. | @@ -1657,29 +1664,29 @@ existing conservative alternate/history machinery and are outside the added UNKNOWN-history oracle lattice. For known priors, 404.321(a) fixes onset when insured then, otherwise the -first insured quarter. A fully-route flag presumes that prerequisite and -changes nothing else. The rule doesn't test when a flag's status began, and -this reasoning doesn't need that date. Prior periods end before onset, so -overlap reaches only the onset quarter, through a prior that ends there. -That prior was itself insured, and 404.130(a) makes fully insured status -part of every rule, so the person met it when the prior began. Fully -insured status compares QCs with a requirement. QCs don't fall, and the -elapsed-year count skips every year any part of which falls in the prior, -so the status still holds in the onset quarter. -The recent scan now holds one complete annual -placement and prior treatment fixed before selecting that first quarter; -a later clear quarter cannot repair an overlapping first quarter. A blind -fully-route declaration is insured at onset and needs a clear onset -quarter. The ordinary constructor also tries bounded annual placements -and fixed prior treatments when its initially favorable onset assignment -overlaps a prior. This preserves the valid converse: moving one annual QC -from Q1 to Q2 can make Q2 the first insured, nonoverlapping start. Both the -possibility proof and the public constructor use that same construction. -The resolved annual filling and prior treatment also supply the public -DISABILITY witness, so its qualifying quarter agrees with that legal -first start rather than reverting to a new favorable onset assignment. -The historical alternate has its own eligible date candidates and retains -its existing continuous clock and lower-credit exclusion. +first insured quarter. The rule does not know when a fully-route flag's +status began. An overlapping quarter fixes the first start only when the +person is ordinarily insured there without any flag, for the same complete +annual filling and all-period treatment. A recent-only witness cannot +supply the missing fully insured prerequisite. The prior may supply that +prerequisite when used and fail to supply it when disregarded; persistence +under one treatment says nothing about the other. The flag can first hold +in a later clear quarter. Blindness removes the recent test under +404.130(e), but does not date the flag's fully insured status either. + +When the initially favorable ordinary start overlaps a prior, construction +still searches at most 4,096 annual placements and both prior treatments. +Finding a clear first start proves possibility. It cannot settle the +elapsed-year freeze, FULLY, CURRENTLY, DISABILITY, and DLI for other lawful +fillings. Construction therefore retains +`disability_boundary_assignments_unsupported`, rather than selecting the +first success. Finding no clear start still proves an input error. +Possibility checks defer a construction refusal so that later input +validation remains first. This deliberately leaves some loose refusals: +keeping a possible lawful row and its weight is safer than rejecting it +without a proof that every filling fails. The historical alternate retains +its own eligible start candidates, continuous clock, and lower-credit +exclusion; no flag-specific substantive condition is adjudicated here. | Invariant | Executed tests | | --- | --- | @@ -1687,16 +1694,16 @@ its existing continuous clock and lower-credit exclusion. | Blind fully routes without prior overlap preserve their zero-credit named refusal; foreign and credit-adding routes precede the floor. | `test_blind_fully_route_with_zero_credits_keeps_named_refusal`; `test_foreign_and_credit_adding_routes_precede_floor`; `test_classification_oracle_modern_lattice` | | One alternate start clears overlap, horizon and the 1955 limit together; credited endpoints and false/UNKNOWN establishment retain their treatment. | `test_review_alternate_start_must_clear_same_prior_overlap`; `test_alternate_uses_one_clear_candidate_after_prior_ending_quarter`; `test_unestablished_alternate_keeps_prior_treatment`; `test_classification_oracle_historical_boundary_lattice` | | UNKNOWN priors cannot supply a special route without six credits before age 31, or couple incompatible earliest-prior and current windows. | `test_classification_oracle_unknown_prior_cannot_invent_special_eligibility`; `test_classification_oracle_unknown_prior_must_jointly_insure_current`; `test_classification_oracle_unknown_twenty_qcs_need_one_joint_start`; generated `test_classification_oracle_hypothesis` | -| Each known-prior filling and treatment has one first insured start. Annual flexibility can delay that start, but an already insured overlapping onset cannot be repaired by a later candidate. | `test_classification_oracle_fully_flag_cannot_delay_an_insured_onset`; `test_classification_oracle_blind_fully_flag_still_has_one_first_start`; `test_classification_oracle_annual_placement_can_delay_first_insured_quarter`; `test_classification_oracle_annual_placement_boundary_lattice`; `test_disability_witness_uses_the_legal_annual_start_filling` | +| Each known-prior filling and treatment has one first insured start. Only ordinary insurance without a flag fixes an overlapping quarter. A clear start requiring a different placement or treatment keeps a named refusal, rather than settling statuses by iteration order. | `test_classification_oracle_fully_flag_cannot_delay_an_insured_onset`; `test_classification_oracle_blind_fully_flag_still_has_one_first_start`; `test_classification_oracle_annual_placement_can_delay_first_insured_quarter`; `test_classification_oracle_annual_placement_boundary_lattice`; `test_disability_witness_uses_the_legal_annual_start_filling` | | Invalid declarations have zero rows and weight; each valid computed or named-refusal outcome has exactly one row and its full rational weight. | Every new regression and lattice evaluation; `test_classification_oracle_hypothesis` | ### Independent oracle and bounds `tests/test_track_b_insured_status_classification_oracle.py` uses public input/evaluator types and plain arithmetic. It calls no private rule -helper. Its 4,819 deterministic declarations and 48 generated examples -plus an explicit example vary modern ages 24, 29, 42 and 60; historical -births 1890, 1900 and 1910; onset and end quarters around 1952–1956; +helper. Its modern lattice has 3,168 declarations. Together with the +historical and boundary lattices and 48 generated examples plus an explicit +example, it varies modern ages 24, 29, 42 and 60; historical births 1890, 1900 and 1910; onset and end quarters around 1952–1956; recovery, continuity, death and exit bounds; none, one, two, special and UNKNOWN priors; blindness; all four fully routes, the alternate and flag pairs; credits 0, 5, 6, 19, 20 and 24 in old, recent and boundary placements; @@ -1710,16 +1717,27 @@ query plus the FRA/death continuation cap. At most two observed annual totals are partial and two years UNKNOWN; the largest selected placement space is 192. UNKNOWN history includes every empty/one-period quarter interval in its stated range, with exact endings before onset, plus a -bounded two-period class consisting of a blind fully-route prefix and -subsequent special period. A prior start must itself be insured. This +bounded two-period class consisting of an independently fully insured +blind prefix, with or without a fully-route flag, ending immediately before +a subsequent special period. Gapped or arbitrary two-period histories are +not exhausted. The earlier flagged birth-to-before-first-QC blind prefix +followed by a later special interval is preserved as a separate gapped +representative class. A prior start must itself be insured. This preserves the defensible historical-blindness completion even when current blindness is false. The oracle does not exhaust arbitrary two-period or three-or-more UNKNOWN histories, alternate-founded UNKNOWN prior starts, raw earnings, credit-adding flags, foreign routes, administrative filing facts or SSPA211. Negative UNKNOWN examples have separate impossibility -proofs that also exclude extra periods. Classification is the tested -principle; returned DLI and per-test diagnostic assignment coherence are -outside this oracle's claim. +proofs that also exclude extra periods. A fully-route flag's first quarter +is free: every candidate start, one quarter before onset, and a quarter after the start horizon are considered. +UNKNOWN history also admits historical candidates and a before-birth +sentinel, with one common flag start for the entire history. The modern +288-base deterministic flag-relaxation property checks four flags per base +(1,152 implications) using the same cached public outcomes. Classification +is this oracle's tested principle; returned DLI and per-test diagnostic +assignment coherence are outside its claim. The separate status oracle +below checks returned Booleans, and the reversal properties check complete +public results including deterministic diagnostic witnesses. ### Executed counterexamples and corrected oracle assumptions @@ -1735,23 +1753,117 @@ credits, first failures and dispositions are retained in the round-13 report. These corrections change classification and denominator inclusion, not a computed payment. -Two oracle assumptions were corrected: it initially permitted a later -ordinary start after an insured overlapping onset, contrary to 404.321(a), -and it initially omitted a past-blindness prefix from UNKNOWN histories. -The corrected oracle fixes the first insured quarter within each filling -and permits that historical blindness completion. No unexplained or -silently accepted disagreement is intended. +Round 13 corrected an oracle that permitted a later ordinary start after +an insured overlapping onset. Round 14 corrects the remaining flag premise: +a flag is not fully insured in every quarter. Its first fully insured +quarter is a free fact, shared by a complete history. The oracle also +admits a single no-flag blind prior and blind-then-special prefixes wherever +ordinary fully insured status permits their first start. Current +nonblindness cannot exclude past blindness. The separate status oracle +checks favorable returned Booleans rather than classification alone. The round-11 four fully-route assertions for six credits first earned -after age 31 are retained unchanged as the dispatch explicitly requires. -The joint proof exposes their incompatibility with 404.130(d)'s special -prior premise. Any resulting failures are reported individually; those -assertions are not weakened or relabeled as passing. +after age 31 now require `InvalidFamilyInput`: those late credits cannot +supply the necessary special prior. The early six-credit control retains +its named refusal because an under-31 special prior remains possible. +These final assertions strengthen classification coverage; the earlier +claim that they were left unchanged was incorrect. Mutation checks are recorded in [`track_b_insured_status_mutations.json`](track_b_insured_status_mutations.json). Every recorded implementation mutation was caught and reverted. + +## Round 14 lawful fillings and returned statuses + +Verification class: statutory conformance on invented declarations only. +This correction admits no population, behavioral, payment, or forecast claim. + +The 1951-born nonblind worker's six earlier QCs permit a blind prior from +1973-04-01 through 1975-12-31, followed by under-31 special insurance at the +1976 onset. The joint optimistic proof already permitted that history; +the later emptiness check now permits it too. The UNKNOWN-prior row and +weight 17/9 survive, including an explicit exit, a claiming-age query, +and the 1995 blind-then-special variant. + +For the 1924-born worker, disregarding the 1979–1985 prior gives 20 recent +QCs in 1985Q1 but only 33 of 34 fully insured QCs. In Q2, 34 of 34 fully +insured QCs and the recent rule hold together. Thus the four fully-route +flags cannot reject a declaration that is ordinary-valid without them. +Each retains its own named refusal and weight 3/2. The no-flag control +computes FULLY true. This fixes a false rejection rather than choosing a +new reading of 404.321(a). + +For the 1960-born worker, annual QCs 1990:1, 1995–1998:4 each, 1999:2, +2000:1, and 2002:1 admit 1990Q3, 1999Q1/Q2, 2000Q2, and 2002Q4. Favorable +prior disregard starts the current period in 2000Q2 and computes FULLY +20/20 at 2006-01-01; the previously selected 2002Q1 start computed 20/21. +The implementation now refuses that unresolved start for every requested +test, with one row and its full weight. Adding four QCs in each year +2003–2006 and querying at 2022-03-01 similarly exposes 36/36 versus 36/37. +No benefit amount is computed in either case. + +Reversing annual boundary candidates also exposed equal-score diagnostic +witnesses selected by iteration order, with unchanged statuses. Boundary +options now use canonical tuple order so the complete public result remains +deterministic; no statutory amount or status calculation changes. + +The invariants added in this round are executed by public example and +Hypothesis tests in `test_track_b_insured_status_fix_round_14.py` and the +independent status oracle: adding a fully-route flag preserves every row; +reversing annual-placement and prior-treatment iteration preserves public +results; admitting past blindness preserves UNKNOWN-history rows; every +computed status equals the most favorable lawful filling in the oracle's +bounded space. Existing impossible-overlap, six-QC, horizon, recovery, +continuous-clock, and FRA invariants remain in force. + +### Premise attacks and source readings + +The pre-1913 male cohort attacks include a prior needed to recover old +20/40 QCs, and the blind-then-special attack independently computes six +recent QCs and a seven-of-six fully insured prerequisite. Both preserve +UNKNOWN-history rows. The disability elapsed-year rule in 404.132(b), +rather than the retirement calendar in 404.110(b), governs a prior that +must begin before FRA. + +An attempted aggregate-funded blind prior was also executed and minimized. +It is not a proved lawful no-flag completion: RS 00301.315 B.1 expressly +says, "The simplified method does not apply to disability claims." The +general incorporation of 404.110 by 404.132, including the aggregate method +in paragraph (d), suggests a broader alternative reading. The default +follows the explicit disability-specific POMS exclusion. The existing +`SIMPLIFIED_PRE1951` declared condition represents the alternative as a +named refusal without adjudicating its basis or computing a disability +period from aggregate credits. The two public controls are +`test_unchanged_simplified_prior_basis_does_not_insure_disability` and +`test_unchanged_declared_simplified_prior_basis_keeps_named_refusal`. +The report gives both source texts and the invented QC difference; no +payment is computed and no additional statutory approval is requested. + +Eleven isolated implementation mutations were caught, including all ten +requested rules and the additional canonical diagnostic tie rule. Exact +commands, failing test nodes, zero-open audit counts, and the final +implementation hash are retained in `track_b_insured_status_mutations.json`. + +### Independent status oracle and bounds + +`tests/test_track_b_insured_status_status_oracle.py` calls public types and +function entry points, with no rule helpers. It enumerates known annual +QC totals, no prior or one known prior, known ends, no flags, both medical +blindness states, and all-use/all-disregard treatment. Each fixed filling +finds its first insured start before building the period and independently +computing FULLY, CURRENTLY, and DISABILITY. Computed public Booleans must +match the componentwise most favorable answer over lawful fillings; a +named refusal preserves a row. Query cases include dates well after the +period ends and a claiming-age query. At most 576 placements, two +establishment treatments and two status treatments are considered per declaration. The 36 deterministic lattice +cases, the reviewer case, and 24 generated examples plus the explicit +reviewer example cover women born 1960-02-02. The executable module header +gives the remaining finite bounds; run times and every observed +disagreement are recorded in `scratch/review/fix-round-14-report.md`. +DLI, raw earnings, UNKNOWN earnings/ends, foreign routes, and specialist +flags are outside this oracle's claim. + ## Not in scope No real data, population evaluation, baseline claiming hazard, behavioral diff --git a/docs/design/track_b_insured_status_mutations.json b/docs/design/track_b_insured_status_mutations.json index a3897b966..b9d5713b3 100644 --- a/docs/design/track_b_insured_status_mutations.json +++ b/docs/design/track_b_insured_status_mutations.json @@ -4367,5 +4367,367 @@ "round_13_note": "Sixteen isolated in-memory mutations were caught against the final source. Every run used named invented-data tests with nonexistent data roots, bounded threads, zero restricted opens and zero spawned-process audit events. Original source bytes were checked unchanged after each mutation. Oracle route-removal controls, coupled prior/current checks, first-start and annual-placement repairs, and the DISABILITY carried-filling repair all bite.", "round_13_oracle_test_sha256": "4ffa46ffb24f7b8793eb2395a08e9f7c1eea4f784019dc8f3e17351a7f25718e", "round_13_replay": "Write round_13_runner_source to scratch/review/run_round13_named.py. For each record, write name/source_sha256/changes to its spec_path, then execute its exact command. Each mutation applies only in memory and the runner verifies unchanged source bytes.", - "round_13_final_source_sha256": "1234c1cf5f199b92a102d71ad3c41f7a177ca242df626a97eaf6b4e9b889771d" + "round_13_final_source_sha256": "1234c1cf5f199b92a102d71ad3c41f7a177ca242df626a97eaf6b4e9b889771d", + "round_14_mutations": [ + { + "name": "restore_current_nonblindness_in_emptiness", + "source_sha256": "cd059a32b8267b9d62913ff4a61285a643c08c095c14bebeff69c49b7a9b4e4e", + "changes": [ + { + "before": " replace(plain, statutory_blindness=True),", + "after": " plain," + } + ], + "node": "tests/test_track_b_insured_status_fix_round_14.py::test_unknown_prior_history_keeps_historical_blindness", + "spec_path": "scratch/review/round14-mutation-restore_current_nonblindness_in_emptiness.json", + "log": "scratch/review/round14-mutation-restore_current_nonblindness_in_emptiness.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round14 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round14 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND14_MUTATION=scratch/review/round14-mutation-restore_current_nonblindness_in_emptiness.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round14_named.py -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_insured_status_fix_round_14.py::test_unknown_prior_history_keeps_historical_blindness > scratch/review/round14-mutation-restore_current_nonblindness_in_emptiness.log 2>&1", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_14.py::test_unknown_prior_history_keeps_historical_blindness[single-InsuredTest.FULLY]", + "tests/test_track_b_insured_status_fix_round_14.py::test_unknown_prior_history_keeps_historical_blindness[single-InsuredTest.DISABILITY]", + "tests/test_track_b_insured_status_fix_round_14.py::test_unknown_prior_history_keeps_historical_blindness[coverage-end-InsuredTest.FULLY]", + "tests/test_track_b_insured_status_fix_round_14.py::test_unknown_prior_history_keeps_historical_blindness[coverage-end-InsuredTest.DISABILITY]", + "tests/test_track_b_insured_status_fix_round_14.py::test_unknown_prior_history_keeps_historical_blindness[claiming-age-InsuredTest.FULLY]", + "tests/test_track_b_insured_status_fix_round_14.py::test_unknown_prior_history_keeps_historical_blindness[claiming-age-InsuredTest.DISABILITY]", + "tests/test_track_b_insured_status_fix_round_14.py::test_unknown_prior_history_keeps_historical_blindness[subsequent-special-InsuredTest.FULLY]", + "tests/test_track_b_insured_status_fix_round_14.py::test_unknown_prior_history_keeps_historical_blindness[subsequent-special-InsuredTest.DISABILITY]" + ], + "pytest_summary": "8 failed in 26.74s", + "audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "killed": true, + "source_restored": true, + "restoration": "Mutation executes only in the imported module namespace; the runner asserts implementation bytes unchanged on exit." + }, + { + "name": "break_at_recent_only_overlapping_quarter", + "source_sha256": "cd059a32b8267b9d62913ff4a61285a643c08c095c14bebeff69c49b7a9b4e4e", + "changes": [ + { + "before": " if ordinary:\n break", + "after": " if rule_met:\n break" + } + ], + "node": "tests/test_track_b_insured_status_fix_round_14.py::test_recent_only_overlap_does_not_disprove_flagged_start", + "spec_path": "scratch/review/round14-mutation-break_at_recent_only_overlapping_quarter.json", + "log": "scratch/review/round14-mutation-break_at_recent_only_overlapping_quarter.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round14 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round14 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND14_MUTATION=scratch/review/round14-mutation-break_at_recent_only_overlapping_quarter.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round14_named.py -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_insured_status_fix_round_14.py::test_recent_only_overlap_does_not_disprove_flagged_start > scratch/review/round14-mutation-break_at_recent_only_overlapping_quarter.log 2>&1", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_14.py::test_recent_only_overlap_does_not_disprove_flagged_start[ordinary-query-CoverageCondition.DEEMED_FULLY_INSURED]", + "tests/test_track_b_insured_status_fix_round_14.py::test_recent_only_overlap_does_not_disprove_flagged_start[ordinary-query-CoverageCondition.TRANSITIONAL_INSURED]", + "tests/test_track_b_insured_status_fix_round_14.py::test_recent_only_overlap_does_not_disprove_flagged_start[ordinary-query-CoverageCondition.EARNED_BASIS]", + "tests/test_track_b_insured_status_fix_round_14.py::test_recent_only_overlap_does_not_disprove_flagged_start[ordinary-query-CoverageCondition.SIMPLIFIED_PRE1951]", + "tests/test_track_b_insured_status_fix_round_14.py::test_recent_only_overlap_does_not_disprove_flagged_start[coverage-end-CoverageCondition.DEEMED_FULLY_INSURED]", + "tests/test_track_b_insured_status_fix_round_14.py::test_recent_only_overlap_does_not_disprove_flagged_start[coverage-end-CoverageCondition.TRANSITIONAL_INSURED]", + "tests/test_track_b_insured_status_fix_round_14.py::test_recent_only_overlap_does_not_disprove_flagged_start[coverage-end-CoverageCondition.EARNED_BASIS]", + "tests/test_track_b_insured_status_fix_round_14.py::test_recent_only_overlap_does_not_disprove_flagged_start[coverage-end-CoverageCondition.SIMPLIFIED_PRE1951]", + "tests/test_track_b_insured_status_fix_round_14.py::test_recent_only_overlap_does_not_disprove_flagged_start[claiming-age-CoverageCondition.DEEMED_FULLY_INSURED]", + "tests/test_track_b_insured_status_fix_round_14.py::test_recent_only_overlap_does_not_disprove_flagged_start[claiming-age-CoverageCondition.TRANSITIONAL_INSURED]", + "tests/test_track_b_insured_status_fix_round_14.py::test_recent_only_overlap_does_not_disprove_flagged_start[claiming-age-CoverageCondition.EARNED_BASIS]", + "tests/test_track_b_insured_status_fix_round_14.py::test_recent_only_overlap_does_not_disprove_flagged_start[claiming-age-CoverageCondition.SIMPLIFIED_PRE1951]" + ], + "pytest_summary": "12 failed in 31.71s", + "audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "killed": true, + "source_restored": true, + "restoration": "Mutation executes only in the imported module namespace; the runner asserts implementation bytes unchanged on exit." + }, + { + "name": "never_stop_at_ordinary_overlap", + "source_sha256": "cd059a32b8267b9d62913ff4a61285a643c08c095c14bebeff69c49b7a9b4e4e", + "changes": [ + { + "before": " if ordinary:\n break", + "after": " if False:\n break" + } + ], + "node": "tests/test_track_b_insured_status_fix_round_14.py::test_unchanged_1962_ordinary_overlap_fixes_start", + "spec_path": "scratch/review/round14-mutation-never_stop_at_ordinary_overlap.json", + "log": "scratch/review/round14-mutation-never_stop_at_ordinary_overlap.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round14 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round14 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND14_MUTATION=scratch/review/round14-mutation-never_stop_at_ordinary_overlap.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round14_named.py -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_insured_status_fix_round_14.py::test_unchanged_1962_ordinary_overlap_fixes_start > scratch/review/round14-mutation-never_stop_at_ordinary_overlap.log 2>&1", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_14.py::test_unchanged_1962_ordinary_overlap_fixes_start[CoverageCondition.DEEMED_FULLY_INSURED]", + "tests/test_track_b_insured_status_fix_round_14.py::test_unchanged_1962_ordinary_overlap_fixes_start[CoverageCondition.TRANSITIONAL_INSURED]", + "tests/test_track_b_insured_status_fix_round_14.py::test_unchanged_1962_ordinary_overlap_fixes_start[CoverageCondition.EARNED_BASIS]", + "tests/test_track_b_insured_status_fix_round_14.py::test_unchanged_1962_ordinary_overlap_fixes_start[CoverageCondition.SIMPLIFIED_PRE1951]" + ], + "pytest_summary": "4 failed in 5.79s", + "audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "killed": true, + "source_restored": true, + "restoration": "Mutation executes only in the imported module namespace; the runner asserts implementation bytes unchanged on exit." + }, + { + "name": "mix_treatments_for_ordinary_start", + "source_sha256": "cd059a32b8267b9d62913ff4a61285a643c08c095c14bebeff69c49b7a9b4e4e", + "changes": [ + { + "before": " InsuredTest.DISABILITY,\n use_periods_only=treatment,\n )[0]\n rule_met", + "after": " InsuredTest.DISABILITY,\n )[0]\n rule_met" + } + ], + "node": "tests/test_track_b_insured_status_fix_round_14.py::test_one_treatment_overlaps_and_the_other_leaves_a_clear_start", + "spec_path": "scratch/review/round14-mutation-mix_treatments_for_ordinary_start.json", + "log": "scratch/review/round14-mutation-mix_treatments_for_ordinary_start.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round14 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round14 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND14_MUTATION=scratch/review/round14-mutation-mix_treatments_for_ordinary_start.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round14_named.py -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_insured_status_fix_round_14.py::test_one_treatment_overlaps_and_the_other_leaves_a_clear_start > scratch/review/round14-mutation-mix_treatments_for_ordinary_start.log 2>&1", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_14.py::test_one_treatment_overlaps_and_the_other_leaves_a_clear_start[CoverageCondition.DEEMED_FULLY_INSURED]", + "tests/test_track_b_insured_status_fix_round_14.py::test_one_treatment_overlaps_and_the_other_leaves_a_clear_start[CoverageCondition.TRANSITIONAL_INSURED]", + "tests/test_track_b_insured_status_fix_round_14.py::test_one_treatment_overlaps_and_the_other_leaves_a_clear_start[CoverageCondition.EARNED_BASIS]", + "tests/test_track_b_insured_status_fix_round_14.py::test_one_treatment_overlaps_and_the_other_leaves_a_clear_start[CoverageCondition.SIMPLIFIED_PRE1951]" + ], + "pytest_summary": "4 failed, 1 passed in 12.29s", + "audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "killed": true, + "source_restored": true, + "restoration": "Mutation executes only in the imported module namespace; the runner asserts implementation bytes unchanged on exit." + }, + { + "name": "restore_onset_only_blind_flag_branch", + "source_sha256": "cd059a32b8267b9d62913ff4a61285a643c08c095c14bebeff69c49b7a9b4e4e", + "changes": [ + { + "before": " if fully_route and person.statutory_blindness:\n return _recent_rule_possible(\n person, credits, horizon, exit_month, lower_credits=lower_credits\n )", + "after": " if fully_route and person.statutory_blindness:\n return _outside_prior_periods(person, _qid(person.disability_onset))" + } + ], + "node": "tests/test_track_b_insured_status_fix_round_14.py::test_blind_flagged_zero_qcs_keep_named_refusal", + "spec_path": "scratch/review/round14-mutation-restore_onset_only_blind_flag_branch.json", + "log": "scratch/review/round14-mutation-restore_onset_only_blind_flag_branch.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round14 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round14 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND14_MUTATION=scratch/review/round14-mutation-restore_onset_only_blind_flag_branch.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round14_named.py -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_insured_status_fix_round_14.py::test_blind_flagged_zero_qcs_keep_named_refusal > scratch/review/round14-mutation-restore_onset_only_blind_flag_branch.log 2>&1", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_14.py::test_blind_flagged_zero_qcs_keep_named_refusal[True-CoverageCondition.DEEMED_FULLY_INSURED]", + "tests/test_track_b_insured_status_fix_round_14.py::test_blind_flagged_zero_qcs_keep_named_refusal[True-CoverageCondition.TRANSITIONAL_INSURED]", + "tests/test_track_b_insured_status_fix_round_14.py::test_blind_flagged_zero_qcs_keep_named_refusal[True-CoverageCondition.EARNED_BASIS]", + "tests/test_track_b_insured_status_fix_round_14.py::test_blind_flagged_zero_qcs_keep_named_refusal[True-CoverageCondition.SIMPLIFIED_PRE1951]" + ], + "pytest_summary": "4 failed, 4 passed in 4.34s", + "audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "killed": true, + "source_restored": true, + "restoration": "Mutation executes only in the imported module namespace; the runner asserts implementation bytes unchanged on exit." + }, + { + "name": "remove_blind_all_clear_fast_path", + "source_sha256": "cd059a32b8267b9d62913ff4a61285a643c08c095c14bebeff69c49b7a9b4e4e", + "changes": [ + { + "before": " if person.statutory_blindness:\n return True\n return any(", + "after": " return any(" + } + ], + "node": "tests/test_track_b_insured_status_fix_round_14.py::test_blind_flagged_zero_qcs_keep_named_refusal", + "spec_path": "scratch/review/round14-mutation-remove_blind_all_clear_fast_path.json", + "log": "scratch/review/round14-mutation-remove_blind_all_clear_fast_path.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round14 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round14 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND14_MUTATION=scratch/review/round14-mutation-remove_blind_all_clear_fast_path.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round14_named.py -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_insured_status_fix_round_14.py::test_blind_flagged_zero_qcs_keep_named_refusal > scratch/review/round14-mutation-remove_blind_all_clear_fast_path.log 2>&1", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_14.py::test_blind_flagged_zero_qcs_keep_named_refusal[False-CoverageCondition.DEEMED_FULLY_INSURED]", + "tests/test_track_b_insured_status_fix_round_14.py::test_blind_flagged_zero_qcs_keep_named_refusal[False-CoverageCondition.TRANSITIONAL_INSURED]", + "tests/test_track_b_insured_status_fix_round_14.py::test_blind_flagged_zero_qcs_keep_named_refusal[False-CoverageCondition.EARNED_BASIS]", + "tests/test_track_b_insured_status_fix_round_14.py::test_blind_flagged_zero_qcs_keep_named_refusal[False-CoverageCondition.SIMPLIFIED_PRE1951]" + ], + "pytest_summary": "4 failed, 4 passed in 4.64s", + "audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "killed": true, + "source_restored": true, + "restoration": "Mutation executes only in the imported module namespace; the runner asserts implementation bytes unchanged on exit." + }, + { + "name": "return_first_successful_filling", + "source_sha256": "cd059a32b8267b9d62913ff4a61285a643c08c095c14bebeff69c49b7a9b4e4e", + "changes": [ + { + "before": " _refuse(\n InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY,\n \"First insured start depends on annual placement \"\n \"or prior treatment\",\n )", + "after": " return _with_current_period(\n person, filling, month, exit_month,\n use_periods_only=treatment,\n )" + } + ], + "node": "tests/test_track_b_insured_status_fix_round_14.py::test_first_successful_placement_cannot_settle_status", + "spec_path": "scratch/review/round14-mutation-return_first_successful_filling.json", + "log": "scratch/review/round14-mutation-return_first_successful_filling.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round14 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round14 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND14_MUTATION=scratch/review/round14-mutation-return_first_successful_filling.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round14_named.py -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_insured_status_fix_round_14.py::test_first_successful_placement_cannot_settle_status > scratch/review/round14-mutation-return_first_successful_filling.log 2>&1", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_14.py::test_first_successful_placement_cannot_settle_status[ordinary-query-InsuredTest.ALL]", + "tests/test_track_b_insured_status_fix_round_14.py::test_first_successful_placement_cannot_settle_status[ordinary-query-InsuredTest.FULLY]", + "tests/test_track_b_insured_status_fix_round_14.py::test_first_successful_placement_cannot_settle_status[ordinary-query-InsuredTest.CURRENTLY]", + "tests/test_track_b_insured_status_fix_round_14.py::test_first_successful_placement_cannot_settle_status[ordinary-query-InsuredTest.DISABILITY]", + "tests/test_track_b_insured_status_fix_round_14.py::test_first_successful_placement_cannot_settle_status[coverage-end-InsuredTest.ALL]", + "tests/test_track_b_insured_status_fix_round_14.py::test_first_successful_placement_cannot_settle_status[coverage-end-InsuredTest.FULLY]", + "tests/test_track_b_insured_status_fix_round_14.py::test_first_successful_placement_cannot_settle_status[coverage-end-InsuredTest.CURRENTLY]", + "tests/test_track_b_insured_status_fix_round_14.py::test_first_successful_placement_cannot_settle_status[coverage-end-InsuredTest.DISABILITY]", + "tests/test_track_b_insured_status_fix_round_14.py::test_first_successful_placement_cannot_settle_status[claiming-age-InsuredTest.ALL]", + "tests/test_track_b_insured_status_fix_round_14.py::test_first_successful_placement_cannot_settle_status[claiming-age-InsuredTest.FULLY]", + "tests/test_track_b_insured_status_fix_round_14.py::test_first_successful_placement_cannot_settle_status[claiming-age-InsuredTest.CURRENTLY]", + "tests/test_track_b_insured_status_fix_round_14.py::test_first_successful_placement_cannot_settle_status[claiming-age-InsuredTest.DISABILITY]" + ], + "pytest_summary": "12 failed in 6.70s", + "audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "killed": true, + "source_restored": true, + "restoration": "Mutation executes only in the imported module namespace; the runner asserts implementation bytes unchanged on exit." + }, + { + "name": "reject_clear_filling_instead_of_refusing", + "source_sha256": "cd059a32b8267b9d62913ff4a61285a643c08c095c14bebeff69c49b7a9b4e4e", + "changes": [ + { + "before": " _refuse(\n InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY,\n \"First insured start depends on annual placement \"\n \"or prior treatment\",\n )", + "after": " raise InvalidFamilyInput(\n \"First insured start depends on annual placement \"\n \"or prior treatment\"\n )" + } + ], + "node": "tests/test_track_b_insured_status_fix_round_14.py::test_first_successful_placement_cannot_settle_status", + "spec_path": "scratch/review/round14-mutation-reject_clear_filling_instead_of_refusing.json", + "log": "scratch/review/round14-mutation-reject_clear_filling_instead_of_refusing.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round14 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round14 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND14_MUTATION=scratch/review/round14-mutation-reject_clear_filling_instead_of_refusing.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round14_named.py -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_insured_status_fix_round_14.py::test_first_successful_placement_cannot_settle_status > scratch/review/round14-mutation-reject_clear_filling_instead_of_refusing.log 2>&1", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_14.py::test_first_successful_placement_cannot_settle_status[ordinary-query-InsuredTest.ALL]", + "tests/test_track_b_insured_status_fix_round_14.py::test_first_successful_placement_cannot_settle_status[ordinary-query-InsuredTest.FULLY]", + "tests/test_track_b_insured_status_fix_round_14.py::test_first_successful_placement_cannot_settle_status[ordinary-query-InsuredTest.CURRENTLY]", + "tests/test_track_b_insured_status_fix_round_14.py::test_first_successful_placement_cannot_settle_status[ordinary-query-InsuredTest.DISABILITY]", + "tests/test_track_b_insured_status_fix_round_14.py::test_first_successful_placement_cannot_settle_status[coverage-end-InsuredTest.ALL]", + "tests/test_track_b_insured_status_fix_round_14.py::test_first_successful_placement_cannot_settle_status[coverage-end-InsuredTest.FULLY]", + "tests/test_track_b_insured_status_fix_round_14.py::test_first_successful_placement_cannot_settle_status[coverage-end-InsuredTest.CURRENTLY]", + "tests/test_track_b_insured_status_fix_round_14.py::test_first_successful_placement_cannot_settle_status[coverage-end-InsuredTest.DISABILITY]", + "tests/test_track_b_insured_status_fix_round_14.py::test_first_successful_placement_cannot_settle_status[claiming-age-InsuredTest.ALL]", + "tests/test_track_b_insured_status_fix_round_14.py::test_first_successful_placement_cannot_settle_status[claiming-age-InsuredTest.FULLY]", + "tests/test_track_b_insured_status_fix_round_14.py::test_first_successful_placement_cannot_settle_status[claiming-age-InsuredTest.CURRENTLY]", + "tests/test_track_b_insured_status_fix_round_14.py::test_first_successful_placement_cannot_settle_status[claiming-age-InsuredTest.DISABILITY]" + ], + "pytest_summary": "12 failed in 10.38s", + "audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "killed": true, + "source_restored": true, + "restoration": "Mutation executes only in the imported module namespace; the runner asserts implementation bytes unchanged on exit." + }, + { + "name": "let_search_refusal_escape_possibility", + "source_sha256": "cd059a32b8267b9d62913ff4a61285a643c08c095c14bebeff69c49b7a9b4e4e", + "changes": [ + { + "before": " _with_current_period(plain, credits, horizon, exit_month)\n except InsuredConfigurationUnsupported:\n return True\n except InvalidFamilyInput:", + "after": " _with_current_period(plain, credits, horizon, exit_month)\n except InvalidFamilyInput:" + } + ], + "node": "tests/test_track_b_insured_status_fix_round_14.py::test_search_refusal_waits_for_later_input_validation", + "spec_path": "scratch/review/round14-mutation-let_search_refusal_escape_possibility.json", + "log": "scratch/review/round14-mutation-let_search_refusal_escape_possibility.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round14 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round14 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND14_MUTATION=scratch/review/round14-mutation-let_search_refusal_escape_possibility.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round14_named.py -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_insured_status_fix_round_14.py::test_search_refusal_waits_for_later_input_validation > scratch/review/round14-mutation-let_search_refusal_escape_possibility.log 2>&1", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_14.py::test_search_refusal_waits_for_later_input_validation" + ], + "pytest_summary": "1 failed in 3.48s", + "audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "killed": true, + "source_restored": true, + "restoration": "Mutation executes only in the imported module namespace; the runner asserts implementation bytes unchanged on exit." + }, + { + "name": "skip_overlap_placement_search", + "source_sha256": "cd059a32b8267b9d62913ff4a61285a643c08c095c14bebeff69c49b7a9b4e4e", + "changes": [ + { + "before": " if use_periods_only is None and not _outside_prior_periods(\n person, _qid(quarter)\n ):", + "after": " if False and use_periods_only is None and not _outside_prior_periods(\n person, _qid(quarter)\n ):" + } + ], + "node": "tests/test_track_b_insured_status_fix_round_14.py::test_round_thirteen_annual_start_needs_named_refusal", + "spec_path": "scratch/review/round14-mutation-skip_overlap_placement_search.json", + "log": "scratch/review/round14-mutation-skip_overlap_placement_search.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round14 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round14 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND14_MUTATION=scratch/review/round14-mutation-skip_overlap_placement_search.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round14_named.py -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_insured_status_fix_round_14.py::test_round_thirteen_annual_start_needs_named_refusal > scratch/review/round14-mutation-skip_overlap_placement_search.log 2>&1", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_14.py::test_round_thirteen_annual_start_needs_named_refusal" + ], + "pytest_summary": "1 failed in 2.21s", + "audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "killed": true, + "source_restored": true, + "restoration": "Mutation executes only in the imported module namespace; the runner asserts implementation bytes unchanged on exit." + }, + { + "name": "remove_canonical_boundary_ties", + "source_sha256": "cd059a32b8267b9d62913ff4a61285a643c08c095c14bebeff69c49b7a9b4e4e", + "changes": [ + { + "before": " options = [tuple(sorted(_assignment_candidates(*rows[y]))) for y in years]\n", + "after": " options = [_assignment_candidates(*rows[y]) for y in years]\n" + } + ], + "node": "tests/test_track_b_insured_status_fix_round_14.py::test_assignment_and_treatment_order_leave_public_result_unchanged", + "spec_path": "scratch/review/round14-mutation-remove_canonical_boundary_ties.json", + "log": "scratch/review/round14-mutation-remove_canonical_boundary_ties.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round14 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round14 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND14_MUTATION=scratch/review/round14-mutation-remove_canonical_boundary_ties.json /Users/maxghenis/PolicyEngine/microcosm-dynamics/.venv/bin/python scratch/review/run_round14_named.py -p no:xdist -p no:cacheprovider -q --tb=short tests/test_track_b_insured_status_fix_round_14.py::test_assignment_and_treatment_order_leave_public_result_unchanged > scratch/review/round14-mutation-remove_canonical_boundary_ties.log 2>&1", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_14.py::test_assignment_and_treatment_order_leave_public_result_unchanged[True-False]", + "tests/test_track_b_insured_status_fix_round_14.py::test_assignment_and_treatment_order_leave_public_result_unchanged[True-True]" + ], + "pytest_summary": "2 failed, 1 passed in 6.63s", + "audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "killed": true, + "source_restored": true, + "restoration": "Mutation executes only in the imported module namespace; the runner asserts implementation bytes unchanged on exit." + } + ], + "round_14_runner_source": "\"\"\"Run named invented-data conformance tests with open-event auditing.\"\"\"\n\nimport hashlib\nimport json\nimport os\nfrom pathlib import Path\nimport sys\n\nCOUNTS = {\"restricted_opens\": 0, \"subprocess.Popen\": 0, \"os.system\": 0}\nBARRED = {\n \"gates.yaml\", \"adjusted_poverty.py\", \"rows.py\",\n \"ssa_trust_fund_interest_rates_2026.json\",\n \"urban2010_cola_comparison.md\", \"urban2010_fra68_comparison.md\",\n \"boomers2004_uniform_cut_comparison.md\", \"minimum_benefits_comparison.md\",\n \"m6_projection_engine.md\", \"mint8_table_user_guide.source.html\",\n \"test_anchor_provenance_erratum.py\",\n}\n\n\ndef audit(event, arguments):\n if event == \"open\" and isinstance(arguments[0], (str, bytes)):\n path = os.fsdecode(arguments[0])\n name = Path(path).name\n if (\n name in BARRED\n or name.startswith((\"adjusted_poverty.\", \"rows.\"))\n or \"/PolicyEngine/psid-data/\" in path\n or \"/microcosm-launch-evidence/\" in path\n or \"/dynasim-refs/\" in path\n or \"/claude-501/\" in path\n ):\n COUNTS[\"restricted_opens\"] += 1\n raise RuntimeError(path)\n elif event in (\"subprocess.Popen\", \"os.system\"):\n COUNTS[event] += 1\n\n\ndef main():\n for name in (\"POPULACE_DYNAMICS_PSID_DIR\", \"POPULACE_DYNAMICS_EPUF_DIR\"):\n assert os.environ[name] == \"/nonexistent/trackb-round14\"\n assert sys.argv[1:]\n assert all(\n not argument.startswith(\"tests/\") or \".py\" in argument\n for argument in sys.argv[1:]\n )\n sys.addaudithook(audit)\n from populace_dynamics.track_b import insured_status as insured\n\n source_path = Path(insured.__file__)\n original = source_path.read_bytes()\n baseline_path = os.environ.get(\"TRACKB_ROUND14_SOURCE\")\n if baseline_path:\n baseline = Path(baseline_path).read_bytes()\n exec(compile(baseline, str(source_path), \"exec\"), insured.__dict__)\n print(\"BASELINE\", hashlib.sha256(baseline).hexdigest(), flush=True)\n spec_path = os.environ.get(\"TRACKB_ROUND14_MUTATION\")\n if spec_path:\n spec = json.loads(Path(spec_path).read_text())\n assert hashlib.sha256(original).hexdigest() == spec[\"source_sha256\"]\n source = original.decode()\n for change in spec[\"changes\"]:\n assert source.count(change[\"before\"]) == 1, change[\"before\"]\n source = source.replace(change[\"before\"], change[\"after\"], 1)\n exec(compile(source, str(source_path), \"exec\"), insured.__dict__)\n print(\"MUTATION\", spec[\"name\"], flush=True)\n import pytest\n\n try:\n return pytest.main(sys.argv[1:])\n finally:\n assert source_path.read_bytes() == original\n print(\"OPEN_AUDIT\", json.dumps(COUNTS, sort_keys=True), flush=True)\n\n\nif __name__ == \"__main__\":\n raise SystemExit(main())\n", + "round_14_note": "All ten requested mutations and the canonical diagnostic tie mutation were killed by named public tests. Each run used nonexistent data roots, one thread per library, in-memory mutation only, unchanged implementation bytes, zero restricted opens and zero spawned-process audit events.", + "round_14_test_sha256": { + "tests/test_track_b_insured_status_fix_round_14.py": "b3a75d40c6f7830d5afa3d930b700c981bf4e39d1f29d66b5d7ed1fa405484e7", + "tests/test_track_b_insured_status_classification_oracle.py": "9b04808e9eb81fc2d7ccc4835fffed84837900c11284bd278c8336a0ad2215d2", + "tests/test_track_b_insured_status_status_oracle.py": "4b603ca88ea6b52e518dcc93ef08d67ed49f7604aa1894a3b50baedf47aa2b61" + }, + "round_14_replay": "Write round_14_runner_source to scratch/review/run_round14_named.py. For each round_14_mutations record, write name/source_sha256/changes to its spec_path, then execute its exact command. Mutations apply only in memory.", + "round_14_final_source_sha256": "677f7f812f92ac0b072265b7ea664d046986bcc92c21339140ff4dd737b28048", + "round_14_final_source_note": "Rewrapped two docstring lines after the mutation runs; code unchanged." } diff --git a/src/populace_dynamics/track_b/insured_status.py b/src/populace_dynamics/track_b/insured_status.py index 96ecea19e..42b520119 100644 --- a/src/populace_dynamics/track_b/insured_status.py +++ b/src/populace_dynamics/track_b/insured_status.py @@ -37,7 +37,8 @@ preserve an unmodeled route before every credit-count proof; no totalization minimum or eligibility rule is claimed here. Fully-insured-only flags cannot bypass a failed recent-rule scan under upper credits, but retain a possible -pre1956 alternate. Blindness and unknown prior history disable that scan. +pre1956 alternate. Blindness removes the recent-credit requirement; +UNKNOWN prior history skips the known-history scan. After the stronger minimum proof, every route within the declared credit envelope requires six QCs feasible by the immutable start horizon, except blindness with a fully-insured-only flag. UNKNOWN prior history cannot @@ -47,11 +48,13 @@ UNKNOWN prior history also obeys a joint optimistic-clock proof: even deleting every removable uncredited quarter cannot rescue a declaration whose same credits fail the current route. Past blindness is allowed as -an unresolved prior basis. Known-history fully-route scans keep the first -insured start for each filling; a later clear quarter cannot repair an -overlapping first start. Blind fully-route declarations start at onset. -When construction resolves an annual-placement overlap, its selected -filling and prior treatment also supply the DISABILITY output witness. +an unresolved prior basis, including in the earliest-prior emptiness proof. +Known-history fully-route scans fix the first start only when ordinary +insurance holds for that filling and prior treatment. A flag's first +fully insured quarter is unknown, including for blindness. When a clear +first start depends on annual placement or prior treatment after a favorable +overlapping start, construction retains a named refusal rather than +selecting a filling that could change another returned status. The declared pre1956 flag adds no route beyond the automatic alternate. Flag-specific conditions remain declared facts rather than adjudicated rules. Short DIB-entitled prior periods remain possible. Observable specialist credit @@ -1098,7 +1101,8 @@ def _world( def _boundary_variants(rows, periods): years = sorted({q // 4 for pair in periods for q in pair} & rows.keys()) - options = [_assignment_candidates(*rows[y]) for y in years] + # Canonical ties keep diagnostic witnesses independent of enumeration. + options = [tuple(sorted(_assignment_candidates(*rows[y]))) for y in years] if prod(map(len, options)) > 4096: _refuse( InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, @@ -1286,9 +1290,11 @@ def _unknown_prior_history_is_empty( (404.320(b)(2), 404.321(a)), and fit before onset and FRA. Act216(i) (2)(A) also permits a single DIB-entitled month; 404.315(a)(4) waives waiting in specified cases. No five-month premise is safe here. - Upper-credit witnesses - deliberately overapproximate possibility. A surviving quarter proves - no actual history; it only prevents an invalid-input conclusion. + Historical blindness is possible regardless of current blindness + (404.130(e)); every earliest-prior witness therefore permits it. + Upper-credit witnesses deliberately overapproximate possibility. A + surviving quarter proves no actual history; it only prevents an + invalid-input conclusion. """ if person.disability_onset is None: return False @@ -1340,7 +1346,7 @@ def _unknown_prior_history_is_empty( ): return False if _witness( - plain, + replace(plain, statutory_blindness=True), credits, start, exit_month, @@ -1463,7 +1469,7 @@ def _period_end_unknown(person, month): def _with_current_period( - person, credits, month, exit_month, *, use_periods_only=None, resolved=None + person, credits, month, exit_month, *, use_periods_only=None ): if not person.current_disability_period_established: return person, None @@ -1484,9 +1490,9 @@ def _with_current_period( if use_periods_only is None and not _outside_prior_periods( person, _qid(quarter) ): - # One annual placement and prior treatment must supply the first - # clear insured start. A favorable onset assignment that overlaps - # a prior cannot disprove a different, later first assignment. + # A clear first start proves possibility, not a status shared by + # every filling. Keep the row when annual placement or treatment + # changes that start (404.321(a); RS00301.230). rows, _ = _world(person, credits, _qid(horizon), exit_month, False) options = [_assignment_candidates(*row) for row in rows.values()] if prod(map(len, options)) > 4096: @@ -1501,16 +1507,20 @@ def _with_current_period( } for treatment in (True, False): try: - return _with_current_period( + _with_current_period( person, filling, month, exit_month, use_periods_only=treatment, - resolved=resolved, ) except InvalidFamilyInput: continue + _refuse( + InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, + "First insured start depends on annual placement " + "or prior treatment", + ) # 416(i)(2)(C), 404.321(a): onset day if insured then, otherwise # first day of the first later insured quarter. Application/duration # are administrative facts declared by the caller, never inferred. @@ -1546,8 +1556,6 @@ def _with_current_period( prior_disability_periods_provenance=EarningsProvenance.OBSERVED, prior_disability_periods_convention_id=None, ) - if resolved is not None and use_periods_only is not None: - resolved.update(credits=credits, treatment=use_periods_only) return completed, start @@ -1614,8 +1622,9 @@ def _flagged_establishment_possible(person, years): the six-QC recent floor by the start horizon, including UNKNOWN prior history. UNKNOWN histories also face the joint optimistic-clock proof. With known history they additionally need a first insured start clear - of prior quarters, or the automatic pre1956 alternate. Blindness - supplies insurance at onset and cannot delay that first start. The + of prior quarters, or the automatic pre1956 alternate. A flag's start + is unknown: only ordinary insurance for one filling and treatment + fixes an overlapping first start, including with blindness. The pre1956 flag adds no route beyond the automatic alternate (RS00301.480 A/B.1); that alternate still requires twenty QCs. No flag's own conditions are @@ -1690,17 +1699,21 @@ def _recent_rule_possible( ): """404.130(b)-(d) possibility, relaxing only the fully prerequisite. - A single filling must first qualify outside every supplied prior - quarter (404.321(a)). A later clear quarter cannot repair an earlier - insured start overlapping a prior. Enumerate annual placements and - every unresolved lower filling, retaining favorable prior treatment. - Complexity cannot disprove a specialist declaration. + For one filling and treatment, an overlapping quarter fixes the first + start only if ordinary disability insurance holds without a flag + (404.321(a)). A recent-only witness cannot date a flag's unknown fully + insured status. Blindness has no recent test (404.130(e)). Enumerate + annual placements and unresolved lower fillings, retaining favorable + prior treatment. Complexity cannot disprove a specialist declaration; + this deliberately permits loose refusals rather than losing lawful rows. """ try: candidates = range(_qid(person.disability_onset), _qid(horizon) + 1) if all( _outside_prior_periods(person, quarter) for quarter in candidates ): + if person.statutory_blindness: + return True return any( _witness( person, @@ -1741,17 +1754,30 @@ def _recent_rule_possible( for quarter in range( _qid(person.disability_onset), _qid(horizon) + 1 ): - if _witness( + ordinary = _witness( person, filling, _qdate(quarter), exit_month, InsuredTest.DISABILITY, - ignore_fully_insured=True, use_periods_only=treatment, - )[0]: - if _outside_prior_periods(person, quarter): - return True + )[0] + rule_met = ( + person.statutory_blindness + or ordinary + or _witness( + person, + filling, + _qdate(quarter), + exit_month, + InsuredTest.DISABILITY, + ignore_fully_insured=True, + use_periods_only=treatment, + )[0] + ) + if rule_met and _outside_prior_periods(person, quarter): + return True + if ordinary: break except InsuredConfigurationUnsupported: return True @@ -1876,7 +1902,10 @@ def _could_establish_current_period( route. The alternate's start must itself clear prior-period overlap. UNKNOWN prior histories face an optimistic joint clock that permits past blindness and dominates every number of real prior periods. - Fully-route starts obey 404.321(a), including onset with blindness. + A fully-route flag's starting quarter is unknown. Only ordinary + insurance for one filling and treatment fixes an overlapping first + start, including with blindness (404.321(a)). A construction refusal + preserves possibility until later validation has checked input errors. """ if not person.current_disability_period_established: return True @@ -1904,7 +1933,9 @@ def _could_establish_current_period( return False fully_route = bool(person.conditions & _FULLY_INSURED_ROUTE_CONDITIONS) if fully_route and person.statutory_blindness: - return _outside_prior_periods(person, _qid(person.disability_onset)) + return _recent_rule_possible( + person, credits, horizon, exit_month, lower_credits=lower_credits + ) # 404.130(b)-(d) and RS00301.480 retain at least six QCs even # when UNKNOWN prior history changes the window or special route. rows, _ = _world(person, credits, _qid(horizon), exit_month, False) @@ -1951,6 +1982,8 @@ def _could_establish_current_period( ) try: _with_current_period(plain, credits, horizon, exit_month) + except InsuredConfigurationUnsupported: + return True except InvalidFamilyInput: pass else: @@ -1978,6 +2011,8 @@ def _could_establish_current_period( lower.update({year: ((), 0) for year in unknown}) try: _with_current_period(plain, lower, horizon, exit_month) + except InsuredConfigurationUnsupported: + return True except InvalidFamilyInput: pass else: @@ -2029,6 +2064,8 @@ def _could_establish_current_period( filling.update(zip(unknown, choices, strict=True)) try: _with_current_period(plain, filling, horizon, exit_month) + except InsuredConfigurationUnsupported: + return True except InvalidFamilyInput: continue return True @@ -2094,12 +2131,14 @@ def insured_status( first insured start outside prior quarters, or automatic pre1956 alternate. UNKNOWN history also faces a joint optimistic-clock proof permitting past blindness; survival never claims a concrete history. - Blind fully-route insurance fixes the first start at onset. The - alternate must use one + A fully-route flag's start is unknown, including with blindness; + only ordinary insurance for the same filling and treatment fixes an + overlapping first quarter. The alternate must use one start clearing fixed overlap, the horizon and its 1955 date limit; its prior-period clock and credited endpoints remain unchanged. - A resolved annual start supplies the same filling and prior treatment - to the DISABILITY output, rather than a new favorable onset assignment. + If a clear first start depends on annual placement or prior treatment + after a favorable overlapping start, retain a named boundary refusal. + A first successful filling cannot settle the other requested statuses. The pre1956 flag adds no route beyond the automatic alternate. A flag's own conditions remain declared facts and are not tested. History validation runs first. Uncomputable QC rows use bounded @@ -2184,7 +2223,6 @@ def insured_status( # established period never existed (404.320(a),404.130(f)). Unknown # prior periods cannot be mixed selectively with the current period. uncertain_current_start = False - lo_resolution, hi_resolution = {}, {} if prior_unknown: lo_person = hi_person = person lo_start = hi_start = None @@ -2207,7 +2245,6 @@ def insured_status( lower, month, coverage_end_month, - resolved=lo_resolution, ) hi_person, hi_start = ( _with_current_period( @@ -2215,7 +2252,6 @@ def insured_status( upper, month, coverage_end_month, - resolved=hi_resolution, ) if unknown else (lo_person, lo_start) @@ -2276,19 +2312,10 @@ def insured_status( lo_candidates = [ _decision_witness( p, - ( - lo_resolution.get("credits", lower) - if kind is InsuredTest.DISABILITY - else lower - ), + lower, month, coverage_end_month, kind, - use_periods_only=( - lo_resolution.get("treatment") - if kind is InsuredTest.DISABILITY - else None - ), ) for p in decision_lo_people ] @@ -2296,19 +2323,10 @@ def insured_status( [ _decision_witness( p, - ( - hi_resolution.get("credits", upper) - if kind is InsuredTest.DISABILITY - else upper - ), + upper, month, coverage_end_month, kind, - use_periods_only=( - hi_resolution.get("treatment") - if kind is InsuredTest.DISABILITY - else None - ), ) for p in decision_hi_people ] diff --git a/tests/README-tiers.md b/tests/README-tiers.md index 309d07d1f..c8f859972 100644 --- a/tests/README-tiers.md +++ b/tests/README-tiers.md @@ -39,9 +39,9 @@ pytest --collect-only -q -m oracle_policyengine | tail -1 | Tier | Tests at HEAD | |---|---:| -| `unit` | 21,140 | +| `unit` | 21,273 | | `artifact` | 4,271 | | `integration_psid` | 1,471 | | `reproduction_legacy` | 520 | | `oracle_policyengine` | 308 | -| **Total** | **27,710** | +| **Total** | **27,843** | diff --git a/tests/test_track_b_insured_status_classification_oracle.py b/tests/test_track_b_insured_status_classification_oracle.py index 34bc9daee..6adf9a981 100644 --- a/tests/test_track_b_insured_status_classification_oracle.py +++ b/tests/test_track_b_insured_status_classification_oracle.py @@ -8,27 +8,38 @@ The deterministic lattice contains more than 3,000 declarations, with at most two UNKNOWN credit years (each completed by every permitted quarter subset, up -to sixteen), two observed prior periods, and one UNKNOWN prior period. UNKNOWN +to sixteen), two observed prior periods, and bounded UNKNOWN histories. UNKNOWN history is completed by the empty history and every one-period quarter interval from the first possible credited quarter through the onset quarter, with the end clamped before the onset day. Each start must itself be insured. Special provenance is admitted only for an under31 witness without 20/40. Earlier blindness may supply insurance through fully insured status even when current -blindness is absent. A second bounded class combines a blind prefix from birth -through the quarter before the first QC with every later insured special -interval. This is an explicit bound: arbitrary two-period histories and three -or more UNKNOWN periods are not exhausted. Named negative examples have -separate impossibility proofs that exclude additional periods; a bounded search -alone is not such a proof. +blindness is absent. Two bounded classes combine a blind prefix with a later +special prior: the existing flagged prefix from birth through the quarter +before the first QC, and every fully insured blind start with a prefix ending +immediately before each later insured special start. Each class includes every +possible special ending. Thus no-flag blind prefixes must establish ordinary +fully insured status at their own starts. This is an explicit bound: arbitrary +gapped two-period histories, arbitrary other two-period +histories and three or more UNKNOWN periods are not exhausted. Named negative +examples have separate impossibility proofs that exclude additional periods; +a bounded search alone is not such a proof. UNKNOWN endings enumerate every month end through query, plus the statutory -FRA/death cap. Modern queries are at most four elapsed quarters after onset; -historical queries are in 1968 or 1973 and have known endings. Annual totals -have at most two partly credited observed years; selected cases have at most -192 complete annual placements each. Raw earnings, foreign credits, credit- -adding flags, complex boundary refusals, administrative application facts and -SSPA211 are outside this oracle. Declarations use female sex; the male fully -insured transition for cohorts born before 1913 is outside the bound. The +FRA/death cap. Modern queries are at most four elapsed quarters after onset. +Historical boundary queries are in 1968 or 1973; the no-flag historical blind +controls query in 1977 or 1996. These historical cases have known endings. +Annual totals have at most two partly credited observed years; selected cases +have at most 192 complete annual placements each. A fully-route flag's first +quarter is a free fact: every candidate start, the quarter before onset, and a +quarter after +the start horizon are enumerated. UNKNOWN histories also admit every possible +historical start and a sentinel before birth. One common flag start governs +both prior and current insurance; an established prior does not backdate it. +Raw earnings, foreign credits, credit-adding flags, complex boundary refusals, +administrative application facts and SSPA211 are outside this oracle. +Declarations use female sex; the male fully insured transition for cohorts +born before 1913 is outside the bound. The separate round 13 regression module covers credit-adding routes. Known prior periods are declared established facts and are not re-adjudicated. This oracle checks declaration classification, not coherence across separate assignment @@ -51,7 +62,6 @@ from populace_dynamics.track_b import insured_status as rule from populace_dynamics.track_b.gross_benefits import count_family_outcomes -pytestmark = pytest.mark.unit OBSERVED = rule.EarningsProvenance.OBSERVED UNKNOWN = rule.EarningsProvenance.UNKNOWN WEIGHT = Fraction(17, 9) @@ -299,13 +309,13 @@ def _lookback(start, number, periods, credits): @lru_cache(maxsize=32768) def _ordinary_routes( - person, credits, start, periods, fully_flag, *, special=False + person, credits, start, periods, fully_from, *, special=False ): """All routes for one fixed placement, start and prior treatment.""" used = _usable(credits, start, periods) - fully = fully_flag or len(used) >= _fully_needed( - person, _quarter_date(start), periods - ) + fully = (fully_from is not None and start >= fully_from) or len( + used + ) >= _fully_needed(person, _quarter_date(start), periods) if not fully: return () if person.statutory_blindness: @@ -413,20 +423,24 @@ def _alternate(case, credits, start, periods, prior): return len(used) >= 20 and len(continuous) >= 6 and set(continuous) <= used -def _unknown_priors(case, credits, fully_flag): +def _unknown_priors(case, credits, fully_from): person = case.person yield () if not credits: return stop = _quarter(person.disability_onset) - for first in range(min(credits), stop + 1): - routes = _ordinary_routes(person, credits, first, (), fully_flag) + first_candidate = ( + _quarter(person.birth_date) if fully_from is not None else min(credits) + ) + blind_person = replace(person, statutory_blindness=True) + for first in range(first_candidate, stop + 1): + routes = _ordinary_routes(person, credits, first, (), fully_from) blind_prior = _ordinary_routes( - replace(person, statutory_blindness=True), + blind_person, credits, first, (), - fully_flag, + fully_from, ) if not routes and not blind_prior: continue @@ -454,45 +468,72 @@ def _unknown_priors(case, credits, fully_flag): ), ) - # The two-period bound also admits a historical blind prefix ending - # just before the first credited quarter, followed by a special prior. - # With a fully flag the prefix needs no own QCs. Its earliest start is - # the birth quarter; its end preserves every QC and removes every - # earlier elapsed quarter, so this is the favorable prefix representative. - if not fully_flag or min(credits) >= _quarter( - _attained(person.birth_date, 31) - ): - return + special_stop = min(stop, _quarter(_attained(person.birth_date, 31)) - 1) + # Preserve the existing favorable birth prefix. Its gap before the later + # special start leaves all six QCs available to establish that start. + birth_quarter = _quarter(person.birth_date) prefix_end = _quarter_date(min(credits)) - timedelta(days=1) - if prefix_end < person.birth_date: - return - prefix = EnumeratedPeriod(person.birth_date, prefix_end) - for first in range( - min(credits), - min(stop, _quarter(_attained(person.birth_date, 31)) - 1) + 1, + if prefix_end >= person.birth_date and _ordinary_routes( + blind_person, credits, birth_quarter, (), fully_from ): - routes = _ordinary_routes( - person, credits, first, (prefix,), fully_flag - ) - if "under31" not in routes or "20_of_40" in routes: + prefix = EnumeratedPeriod(person.birth_date, prefix_end) + for first in range(min(credits), special_stop + 1): + yield from _special_after_prefix( + case, credits, fully_from, prefix, first + ) + + # The added two-period class covers contiguous blind-then-special periods. + # Each blind start must independently be fully insured, including when + # no flag exists; current nonblindness says nothing about that prior. + for blind_first in range(first_candidate, special_stop): + if not _ordinary_routes( + blind_person, credits, blind_first, (), fully_from + ): continue - for last in range(first, stop + 1): - end = min( - _month_end( - _quarter_date(last).replace( - month=(_quarter_date(last).month + 2) - ) - ), - person.disability_onset - timedelta(days=1), + for first in range( + max(min(credits), blind_first + 1), special_stop + 1 + ): + prefix = EnumeratedPeriod( + max(person.birth_date, _quarter_date(blind_first)), + _quarter_date(first) - timedelta(days=1), ) - yield ( - prefix, - EnumeratedPeriod( - _quarter_date(first), end, special_insured=True - ), + yield from _special_after_prefix( + case, credits, fully_from, prefix, first ) +def _special_after_prefix(case, credits, fully_from, prefix, first): + person = case.person + routes = _ordinary_routes(person, credits, first, (prefix,), fully_from) + if "under31" not in routes or "20_of_40" in routes: + return + for last in range(first, _quarter(person.disability_onset) + 1): + end = min( + _month_end( + _quarter_date(last).replace( + month=(_quarter_date(last).month + 2) + ) + ), + person.disability_onset - timedelta(days=1), + ) + yield ( + prefix, + EnumeratedPeriod(_quarter_date(first), end, special_insured=True), + ) + + +def _flag_starts(case, horizon): + if not set(case.person.conditions) & set(FULLY_FLAGS): + return (None,) + onset = _quarter(case.person.disability_onset) + first = ( + _quarter(case.person.birth_date) - 1 + if case.person.prior_disability_periods_provenance is UNKNOWN + else onset - 1 + ) + return tuple(range(first, horizon + 2)) + + def _has_valid_filling(case): # Individual fully flags have identical oracle semantics; the alternate # flag adds no route. Canonicalization avoids repeating the enumeration. @@ -514,59 +555,89 @@ def _enumerated_filling(case): # UNKNOWN establishment always has the absent-period completion. if person.current_disability_period_established is not True: return True - fully_flag = bool(set(person.conditions) & set(FULLY_FLAGS)) for credits in _placements(case): - histories = ( - _unknown_priors(case, credits, fully_flag) - if person.prior_disability_periods_provenance is UNKNOWN - else (person.prior_disability_periods,) - ) - for prior in histories: - for ending in _endings(case): - starts = range( - _quarter(person.disability_onset), - _start_horizon(case, ending) + 1, + # Every nonblind route needs at least six actual QCs, regardless of + # a flag's start or any deletion of elapsed quarters by a prior. + if not person.statutory_blindness and len(credits) < 6: + continue + # After age 31 fewer than twenty QCs require a special prior. With + # UNKNOWN history, no QC before age 31 excludes every such prior; + # a blind prior alone never supplies special provenance. + age31 = _quarter(_attained(person.birth_date, 31)) + if ( + not person.statutory_blindness + and len(credits) < 20 + and _quarter(person.disability_onset) >= age31 + and not any( + p.special_insured for p in person.prior_disability_periods + ) + and ( + person.prior_disability_periods_provenance is OBSERVED + or not any(q < age31 for q in credits) + ) + ): + continue + for ending in _endings(case): + horizon = _start_horizon(case, ending) + for fully_from in _flag_starts(case, horizon): + histories = ( + _unknown_priors(case, credits, fully_from) + if person.prior_disability_periods_provenance is UNKNOWN + else (person.prior_disability_periods,) ) - for periods in ((prior, ()) if prior else ((),)): - # 404.321(a) fixes the first insured quarter. A later - # clear quarter cannot repair an already insured but - # overlapping onset quarter for this same filling. - first_ordinary = next( - ( - start - for start in starts - if _ordinary_routes( - person, - credits, - start, - periods, - fully_flag, - special=any(p.special_insured for p in prior), - ) - ), - None, - ) - if first_ordinary is not None and not any( - _quarter(p.start) <= first_ordinary <= _quarter(p.end) - for p in prior + for prior in histories: + if _history_has_clear_start( + case, credits, prior, horizon, fully_from ): return True - for start in starts: - if any( - _quarter(p.start) <= start <= _quarter(p.end) - for p in prior - ): - continue - if _alternate(case, credits, start, periods, prior): - return True return False -def _check_classification(case): - possible = _has_valid_filling(case) - rows = [] +def _history_has_clear_start(case, credits, prior, horizon, fully_from): + person = case.person + starts = range( + _quarter(person.disability_onset), + horizon + 1, + ) + for periods in ((prior, ()) if prior else ((),)): + # 404.321(a) fixes the first insured quarter. A later + # clear quarter cannot repair an already insured but + # overlapping onset quarter for this fixed filling, treatment and f. + first_ordinary = next( + ( + start + for start in starts + if _ordinary_routes( + person, + credits, + start, + periods, + fully_from, + special=any(p.special_insured for p in prior), + ) + ), + None, + ) + if first_ordinary is not None and not any( + _quarter(p.start) <= first_ordinary <= _quarter(p.end) + for p in prior + ): + return True + for start in starts: + if any( + _quarter(p.start) <= start <= _quarter(p.end) for p in prior + ): + continue + if _alternate(case, credits, start, periods, prior): + return True + return False + + +@lru_cache(maxsize=16384) +def _public_rows(case): + """Keep the public observation for direct metamorphic lattice checks.""" try: - rows.append( + return ( rule.evaluate_insured_status( "classification-oracle", WEIGHT, @@ -577,9 +648,16 @@ def _check_classification(case): test=rule.InsuredTest.FULLY, coverage_end_month=case.exit_month, ), - ) + ), ) except rule.InvalidFamilyInput: + return () + + +def _check_classification(case): + possible = _has_valid_filling(case) + rows = _public_rows(case) + if not rows: assert not possible, f"oracle found a concrete filling: {case!r}" else: assert possible, f"oracle found no valid filling: {case!r}" @@ -657,6 +735,30 @@ def test_classification_oracle_modern_lattice(flags): ) +def test_classification_oracle_modern_lattice_fully_flags_only_relax(): + """Every modern unflagged row survives each of the four fully flags.""" + for age, total, placement, blind, established in product( + (24, 29, 42, 60), + (0, 5, 6, 19, 20, 24), + ("old", "recent"), + (False, True), + (False, True, None), + ): + case = _modern_case( + age, total, placement, (), blind, "none", established + ) + if _public_rows(case): + for flag in FULLY_FLAGS: + assert _public_rows( + replace( + case, + person=replace( + case.person, conditions=frozenset((flag,)) + ), + ) + ), (case, flag) + + @pytest.mark.parametrize("flags", FLAG_SETS) def test_classification_oracle_prior_and_unknown_completions(flags): for prior, total in product( @@ -1106,7 +1208,81 @@ def test_classification_oracle_blind_fully_flag_still_has_one_first_start( blind=True, periods=(rule.DisabilityPeriod(date(1999, 1, 1), date(2000, 1, 14)),), ) + assert _has_valid_filling(case) + _check_classification(case) + row = rule.evaluate_insured_status( + "free-flag-start", + WEIGHT, + lambda: rule.insured_status( + case.person, + _history(case), + case.month, + test=rule.InsuredTest.FULLY, + ), + ) + assert row.unsupported.reason is getattr( + rule.InsuredUnsupportedReason, flag.name + ) + assert count_family_outcomes((row,)).weight == WEIGHT + + +@pytest.mark.parametrize("flag", FULLY_FLAGS) +def test_classification_oracle_blind_ordinary_onset_cannot_be_delayed(flag): + """Ordinary fully insurance fixes this overlapping start for every f.""" + case = _declaration( + birth=date(1960, 2, 2), + flags=(flag,), + blind=True, + periods=(rule.DisabilityPeriod(date(1999, 1, 1), date(2000, 1, 14)),), + counts=tuple((year, 4) for year in range(1980, 1990)), + ) assert not _has_valid_filling(case) + with pytest.raises(rule.InvalidFamilyInput): + rule.insured_status(case.person, _history(case), case.month) + _check_classification(case) + + +@pytest.mark.parametrize("two_priors", (False, True)) +def test_classification_oracle_no_flag_historical_blind_prior(two_priors): + """A blind start with six ordinary QCs can precede a special prior.""" + year = 1995 if two_priors else 1976 + case = _declaration( + birth=date(1951, 2, 2), + onset=date(year, 1, 15), + end=date(year, 12, 31), + month=date(year + 1, 1, 1), + prior_unknown=True, + fixed=( + 1970 * 4 + 1, + 1972 * 4 + 1, + 1972 * 4 + 2, + 1972 * 4 + 3, + 1973 * 4, + 1973 * 4 + 1, + 1976 * 4, + ), + ) + assert _has_valid_filling(case) + _check_classification(case) + + +@pytest.mark.parametrize("flag", FULLY_FLAGS) +def test_classification_oracle_free_flag_start_preserves_disregard(flag): + """A recent-only overlapping quarter is not an insured first start.""" + case = _declaration( + birth=date(1924, 1, 2), + onset=date(1985, 2, 15), + end=date(1985, 12, 31), + month=date(1985, 12, 1), + flags=(flag,), + periods=(rule.DisabilityPeriod(date(1979, 1, 1), date(1985, 1, 31)),), + fixed=( + *range(1951 * 4, 1954 * 4 + 1), + *range(1975 * 4 + 1, 1978 * 4), + ), + counts=((1978, 4), (1984, 4), (1985, 4)), + ) + assert _has_valid_filling(case) _check_classification(case) diff --git a/tests/test_track_b_insured_status_fix_round_13.py b/tests/test_track_b_insured_status_fix_round_13.py index 7e5f1c861..a940be088 100644 --- a/tests/test_track_b_insured_status_fix_round_13.py +++ b/tests/test_track_b_insured_status_fix_round_13.py @@ -287,7 +287,7 @@ def test_unestablished_alternate_keeps_prior_treatment(established): def test_disability_witness_uses_the_legal_annual_start_filling(): - """The same placement must supply the start and disability witness.""" + """An unresolved annual start retains its row through a named refusal.""" person = _person( disability_onset=date(2000, 2, 15), conditions=(), @@ -309,9 +309,11 @@ def test_disability_witness_uses_the_legal_annual_start_filling(): person, years, month, test=i.InsuredTest.DISABILITY ), ) - assert row.unsupported is None - assert row.result.current_disability_period_start == date(2000, 4, 1) - assert row.result.disability.qualifying_quarter == date(2000, 4, 1) + assert row.result is None + assert ( + row.unsupported.reason + is i.InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY + ) counts = count_family_outcomes((row,)) - assert counts.rows == 1 and counts.unsupported_rows == 0 - assert counts.weight == WEIGHT and counts.unsupported_weight == 0 + assert counts.rows == counts.unsupported_rows == 1 + assert counts.weight == counts.unsupported_weight == WEIGHT diff --git a/tests/test_track_b_insured_status_fix_round_14.py b/tests/test_track_b_insured_status_fix_round_14.py new file mode 100644 index 000000000..fbd5ab79a --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_14.py @@ -0,0 +1,773 @@ +"""Statutory conformance for the round-fourteen establishment corrections. + +Invented declarations only; no population, behavioral, or forecast claim. +Rows and exact weight survive every named refusal. Tests named ``unchanged`` +pin existing rejection or refusal behavior rather than a new defect. +""" + +from dataclasses import replace +from datetime import date +from fractions import Fraction +from itertools import product + +import pytest +from hypothesis import example, given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as i +from populace_dynamics.track_b.gross_benefits import count_family_outcomes +from tests.test_track_b_insured_status import history + +OBSERVED = i.EarningsProvenance.OBSERVED +UNKNOWN = i.EarningsProvenance.UNKNOWN +WEIGHT = Fraction(17, 9) +FLAG_WEIGHT = Fraction(3, 2) +FULLY_FLAGS = ( + i.CoverageCondition.DEEMED_FULLY_INSURED, + i.CoverageCondition.TRANSITIONAL_INSURED, + i.CoverageCondition.EARNED_BASIS, + i.CoverageCondition.SIMPLIFIED_PRE1951, +) +PROPERTY = settings(max_examples=24, deadline=None) + + +def _person(**changes): + values = dict( + sex=i.Sex.FEMALE, + disability_onset=date(2000, 2, 15), + current_disability_period_established=True, + current_disability_period_provenance=OBSERVED, + current_disability_period_end=date(2002, 12, 31), + current_disability_period_end_provenance=OBSERVED, + prior_disability_periods=( + i.DisabilityPeriod(date(1999, 1, 1), date(2000, 1, 31)), + ), + prior_disability_periods_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + birth = changes.pop("birth", date(1960, 2, 2)) + values.update(changes) + return i.Person(birth, **values) + + +def _row( + person, + years, + month, + *, + test=i.InsuredTest.FULLY, + weight=WEIGHT, + coverage_end=None, +): + row = i.evaluate_insured_status( + "round-fourteen-establishment", + weight, + lambda: i.insured_status( + person, + years, + month, + test=test, + coverage_end_month=coverage_end, + ), + ) + counts = count_family_outcomes((row,)) + assert counts.rows == 1 + assert counts.weight == weight + if row.unsupported: + assert counts.unsupported_rows == 1 + assert counts.unsupported_weight == weight + else: + assert counts.unsupported_rows == 0 + assert counts.unsupported_weight == 0 + return row + + +def _refusal(person, years, month, reason, **kwargs): + row = _row(person, years, month, **kwargs) + assert row.result is None + assert row.unsupported.reason is reason + return row + + +def _blind_history(*, subsequent=False, month=None, coverage_end=None): + onset = date(1995, 1, 15) if subsequent else date(1976, 1, 15) + month = month or date(onset.year + 1, 1, 1) + person = _person( + birth=date(1951, 2, 2), + sex=i.Sex.MALE, + disability_onset=onset, + current_disability_period_end=date(onset.year, 12, 31), + prior_disability_periods=(), + prior_disability_periods_provenance=UNKNOWN, + ) + credited = { + 1970 * 4 + 1, + 1972 * 4 + 1, + 1972 * 4 + 2, + 1972 * 4 + 3, + 1973 * 4, + 1973 * 4 + 1, + 1976 * 4, + } + years = history(person, month, end=coverage_end) + for year in years: + if year < 1978: + years[year] = i.CoverageYear( + OBSERVED, + qc_quarters=tuple(year * 4 + q in credited for q in range(4)), + ) + return person, years, month + + +def _flag_history( + flag=FULLY_FLAGS[0], *, month=date(1985, 12, 1), coverage_end=None +): + person = _person( + birth=date(1924, 1, 2), + disability_onset=date(1985, 2, 15), + current_disability_period_end=date(1985, 12, 31), + prior_disability_periods=( + i.DisabilityPeriod(date(1979, 1, 1), date(1985, 1, 31)), + ), + conditions=(() if flag is None else (flag,)), + ) + counts = { + 1951: 4, + 1952: 4, + 1953: 4, + 1954: 1, + 1975: 3, + 1976: 4, + 1977: 4, + 1978: 4, + 1984: 4, + 1985: 4, + } + years = history(person, month, counts, end=coverage_end) + years[1975] = i.CoverageYear( + OBSERVED, + qc_quarters=(False, True, True, True), + ) + return person, years, month + + +def _placement_history( + *, + month=date(2006, 1, 1), + coverage_end=None, + claiming=False, + round_thirteen=False, +): + person = _person( + current_disability_period_end=( + date(2000, 12, 31) if round_thirteen else date(2002, 12, 31) + ), + ) + counts = { + 1990: 1, + 1995: 4, + 1996: 4, + 1997: 4, + 1998: 4, + 1999: 2, + 2000: 1, + 2002: 1, + } + if round_thirteen: + counts = {1995: 4, 1996: 4, 1997: 4, 1998: 4, 1999: 3, 2000: 1} + if claiming: + counts.update({year: 4 for year in range(2003, 2007)}) + return person, history(person, month, counts, end=coverage_end), month + + +@pytest.mark.parametrize( + "test", (i.InsuredTest.FULLY, i.InsuredTest.DISABILITY) +) +@pytest.mark.parametrize( + "month,coverage_end,subsequent", + ( + (None, None, False), + (None, date(1976, 12, 1), False), + (date(2013, 3, 1), None, False), + (None, None, True), + ), + ids=("single", "coverage-end", "claiming-age", "subsequent-special"), +) +def test_unknown_prior_history_keeps_historical_blindness( + test, month, coverage_end, subsequent +): + person, years, month = _blind_history( + month=month, + coverage_end=coverage_end, + subsequent=subsequent, + ) + row = _row(person, years, month, test=test, coverage_end=coverage_end) + if test is i.InsuredTest.FULLY and month.year == 1977: + assert row.unsupported is None + assert row.result.fully.insured + assert row.result.fully.qc_count_lower == 0 + assert row.result.fully.qc_count_upper == 7 + assert row.result.fully.required == 6 + else: + assert row.result is None + assert ( + row.unsupported.reason + is i.InsuredUnsupportedReason.UNKNOWN_PERIODS + ) + + +@pytest.mark.parametrize("flag", FULLY_FLAGS) +@pytest.mark.parametrize( + "month,coverage_end", + ( + (date(1985, 12, 1), None), + (date(1985, 12, 1), date(1985, 12, 1)), + (date(1986, 1, 1), None), + ), + ids=("ordinary-query", "coverage-end", "claiming-age"), +) +def test_recent_only_overlap_does_not_disprove_flagged_start( + flag, month, coverage_end +): + person, years, month = _flag_history( + flag, + month=month, + coverage_end=coverage_end, + ) + _refusal( + person, + years, + month, + i.InsuredUnsupportedReason[flag.name], + weight=FLAG_WEIGHT, + coverage_end=coverage_end, + ) + + +def test_unchanged_unflagged_disregard_control_is_fully_insured(): + person, years, month = _flag_history(None) + row = _row(person, years, month, weight=FLAG_WEIGHT) + assert row.unsupported is None + assert row.result.fully.insured + + +@pytest.mark.parametrize("test", tuple(i.InsuredTest)) +@pytest.mark.parametrize( + "month,coverage_end,claiming", + ( + (date(2006, 1, 1), None, False), + (date(2006, 1, 1), date(2002, 12, 1), False), + (date(2022, 3, 1), None, True), + ), + ids=("ordinary-query", "coverage-end", "claiming-age"), +) +def test_first_successful_placement_cannot_settle_status( + test, month, coverage_end, claiming +): + person, years, month = _placement_history( + month=month, + coverage_end=coverage_end, + claiming=claiming, + ) + _refusal( + person, + years, + month, + i.InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, + test=test, + coverage_end=coverage_end, + ) + + +def test_round_thirteen_annual_start_needs_named_refusal(): + person, years, month = _placement_history( + month=date(2001, 1, 1), + round_thirteen=True, + ) + _refusal( + person, + years, + month, + i.InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, + test=i.InsuredTest.DISABILITY, + ) + + +def _invalid(person, years, month, *, match="no possible insured", **kwargs): + rows = [] + with pytest.raises(i.InvalidFamilyInput, match=match): + rows.append(_row(person, years, month, **kwargs)) + counts = count_family_outcomes(rows) + assert counts.rows == counts.unsupported_rows == 0 + assert counts.weight == counts.unsupported_weight == 0 + + +@pytest.mark.parametrize("flag", FULLY_FLAGS) +def test_unchanged_ordinary_overlap_cannot_be_delayed_by_a_flag(flag): + """Ordinary insurance at onset in every placement fixes the start.""" + person = _person(conditions=(flag,)) + month = date(2006, 1, 1) + years = history(person, month, {year: 4 for year in range(1985, 2001)}) + _invalid(person, years, month) + + +@pytest.mark.parametrize("flag", FULLY_FLAGS) +def test_unchanged_1962_ordinary_overlap_fixes_start(flag): + person = _person( + birth=date(1910, 2, 2), + disability_onset=date(1962, 2, 15), + current_disability_period_end=date(1962, 8, 31), + prior_disability_periods=( + i.DisabilityPeriod(date(1960, 1, 1), date(1962, 1, 31)), + ), + conditions=(flag,), + ) + month = date(1968, 1, 1) + years = history(person, month) + credited = {*range(1957 * 4, 1961 * 4 + 3), 1962 * 4} + for year in years: + years[year] = i.CoverageYear( + OBSERVED, + qc_quarters=tuple(year * 4 + q in credited for q in range(4)), + ) + _invalid(person, years, month) + + +@pytest.mark.parametrize("flag", FULLY_FLAGS) +@pytest.mark.parametrize("overlap", (False, True)) +def test_blind_flagged_zero_qcs_keep_named_refusal(flag, overlap): + """The clear-onset case is unchanged; an overlap admits a free flag start.""" + person = _person( + statutory_blindness=True, + conditions=(flag,), + prior_disability_periods=( + i.DisabilityPeriod( + date(1999, 1, 1), + date(2000, 1, 31) if overlap else date(1999, 12, 31), + ), + ), + ) + month = date(2006, 1, 1) + _refusal( + person, + history(person, month), + month, + i.InsuredUnsupportedReason[flag.name], + ) + + +@pytest.mark.parametrize("flag", FULLY_FLAGS) +def test_unchanged_blind_ordinary_fully_insured_overlap_is_invalid(flag): + person = _person(statutory_blindness=True, conditions=(flag,)) + month = date(2006, 1, 1) + years = history(person, month, {year: 4 for year in range(1985, 2001)}) + _invalid(person, years, month) + + +@pytest.mark.parametrize("total", (5, 6)) +def test_unchanged_unknown_prior_needs_a_possible_fully_insured_start(total): + person = _person( + prior_disability_periods=(), + prior_disability_periods_provenance=UNKNOWN, + ) + month = date(2006, 1, 1) + # Even six lifetime QCs cannot fully insure any earliest prior: they + # first arrive in 1998, when sixteen are needed without a prior freeze. + # The six-credit case passes the universal floor and still rejects. + _invalid(person, history(person, month, {1998: 4, 1999: total - 4}), month) + + +def test_unchanged_no_placement_can_clear_the_prior_overlap(): + person = _person() + month = date(2006, 1, 1) + years = history(person, month, {year: 4 for year in range(1985, 2001)}) + _invalid(person, years, month) + + +@pytest.mark.parametrize("flag", (None, *FULLY_FLAGS)) +def test_one_treatment_overlaps_and_the_other_leaves_a_clear_start(flag): + # Move four old QCs into the used-prior recent window, keeping the + # lifetime count unchanged. Use now insures the overlapping Q1: + # 20 recent and 29/27 fully. Disregard still has only 33/34 fully + # in Q1, first becoming insured in the clear Q2 with 34/34. + person, years, month = _flag_history(flag) + years[1951] = i.CoverageYear( + OBSERVED, qc_quarters=(False, False, False, False) + ) + years[1974] = i.CoverageYear( + OBSERVED, qc_quarters=(False, True, True, True) + ) + years[1975] = i.CoverageYear( + OBSERVED, qc_quarters=(True, True, True, True) + ) + _refusal( + person, + years, + month, + ( + i.InsuredUnsupportedReason[flag.name] + if flag + else i.InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY + ), + weight=FLAG_WEIGHT, + ) + + +def test_search_refusal_waits_for_later_input_validation(monkeypatch): + person, years, month = _placement_history() + called = [] + + def later_validation(*args, **kwargs): + called.append(True) + raise i.InvalidFamilyInput("later declared input is invalid") + + monkeypatch.setattr(i, "_coverage_checks", later_validation) + _invalid(person, years, month, match="later declared input is invalid") + assert called == [True] + + +def test_unchanged_schema_error_precedes_assignment_search(): + person, years, month = _placement_history() + years.pop(1980) + _invalid( + person, years, month, match="Every coverage year must be declared" + ) + + +def _lattice_declarations(): + """A finite lattice of known annual boundary and fixed-quarter cases.""" + yield _flag_history(None) + yield _placement_history() + yield _placement_history(month=date(2022, 3, 1), claiming=True) + for blind, onset_count, prior_end in product( + (False, True), + (0, 1, 4), + (date(1999, 12, 31), date(2000, 1, 31)), + ): + person = _person( + statutory_blindness=blind, + current_disability_period_end=date(2000, 12, 31), + prior_disability_periods=( + i.DisabilityPeriod(date(1999, 1, 1), prior_end), + ), + ) + month = date(2001, 1, 1) + yield person, history( + person, + month, + {1995: 4, 1996: 4, 1997: 4, 1998: 4, 1999: 3, 2000: onset_count}, + ), month + + +def _classification(person, years, month): + try: + return _row(person, years, month) + except i.InvalidFamilyInput: + return None + + +def _assert_flags_only_relax(person, years, month): + unflagged = _classification(replace(person, conditions=()), years, month) + if unflagged is None: + return + for flag in FULLY_FLAGS: + flagged = _row(replace(person, conditions=(flag,)), years, month) + assert flagged.result is not None or flagged.unsupported is not None + + +def test_fully_route_flag_only_relaxes_deterministic_lattice(): + for person, years, month in _lattice_declarations(): + _assert_flags_only_relax(person, years, month) + + +@PROPERTY +@example(old=2, onset=1, blind=False, overlap=True, historical=True) +@example(old=2, onset=1, blind=False, overlap=True, historical=False) +@given( + old=st.integers(0, 4), + onset=st.integers(0, 4), + blind=st.booleans(), + overlap=st.booleans(), + historical=st.booleans(), +) +def test_fully_route_flag_only_relaxes_generated_declarations( + old, onset, blind, overlap, historical +): + if historical: + person, years, month = _flag_history( + None, month=date(1986, 1, 1) if overlap else date(1985, 12, 1) + ) + _assert_flags_only_relax(person, years, month) + return + person = _person( + statutory_blindness=blind, + prior_disability_periods=( + i.DisabilityPeriod( + date(1999, 1, 1), + date(2000, 1, 31) if overlap else date(1999, 12, 31), + ), + ), + ) + month = date(2006, 1, 1) + years = history( + person, + month, + { + 1990: 1, + 1995: 4, + 1996: 4, + 1997: 4, + 1998: 4, + 1999: old, + 2000: onset, + 2002: 1, + }, + ) + _assert_flags_only_relax(person, years, month) + + +def _outcome(person, years, month): + try: + row = _row(person, years, month) + except i.InvalidFamilyInput as error: + return type(error), str(error) + if row.unsupported: + return ( + row.key, + row.weight, + row.unsupported.reason, + row.unsupported.detail, + ) + return row.key, row.weight, row.result + + +def _reverse_treatments(code): + """Swap only the explicit Boolean treatment tuple, preserving semantics.""" + from types import CodeType + + constants = tuple( + ( + _reverse_treatments(value) + if isinstance(value, CodeType) + else ( + (False, True) + if isinstance(value, tuple) + and len(value) == 2 + and all(type(item) is bool for item in value) + and value == (True, False) + else value + ) + ) + for value in code.co_consts + ) + return code.replace(co_consts=constants) + + +@pytest.mark.parametrize( + "assignment,treatment", ((True, False), (False, True), (True, True)) +) +def test_assignment_and_treatment_order_leave_public_result_unchanged( + monkeypatch, assignment, treatment +): + cases = list(_lattice_declarations()) + cases.append(_flag_history()) + baseline = [_outcome(*case) for case in cases] + if assignment: + original = i._assignment_candidates + monkeypatch.setattr( + i, "_assignment_candidates", lambda *args: original(*args)[::-1] + ) + if treatment: + for function in (i._with_current_period, i._recent_rule_possible): + monkeypatch.setattr( + function, "__code__", _reverse_treatments(function.__code__) + ) + assert [_outcome(*case) for case in cases] == baseline + + +@settings(max_examples=12, deadline=None) +@example(old=2, onset=1, reverse_assignment=True, reverse_treatment=True) +@given( + old=st.integers(0, 4), + onset=st.integers(0, 4), + reverse_assignment=st.booleans(), + reverse_treatment=st.booleans(), +) +def test_assignment_and_treatment_order_generated( + old, onset, reverse_assignment, reverse_treatment +): + person, years, month = _placement_history() + years[1999] = i.CoverageYear(OBSERVED, qc_count=old) + years[2000] = i.CoverageYear(OBSERVED, qc_count=onset) + baseline = _outcome(person, years, month) + with pytest.MonkeyPatch.context() as monkeypatch: + if reverse_assignment: + original = i._assignment_candidates + monkeypatch.setattr( + i, + "_assignment_candidates", + lambda *args: original(*args)[::-1], + ) + if reverse_treatment: + for function in (i._with_current_period, i._recent_rule_possible): + monkeypatch.setattr( + function, + "__code__", + _reverse_treatments(function.__code__), + ) + assert _outcome(person, years, month) == baseline + + +@pytest.mark.parametrize("subsequent", (False, True)) +def test_past_blindness_only_adds_rows_deterministic(subsequent): + person, years, month = _blind_history(subsequent=subsequent) + blind = _row(replace(person, statutory_blindness=True), years, month) + assert blind.result is not None or blind.unsupported is not None + _row(person, years, month) + + +@PROPERTY +@example(subsequent=False, claiming=False, extra=0) +@given( + subsequent=st.booleans(), claiming=st.booleans(), extra=st.integers(0, 4) +) +def test_past_blindness_only_adds_rows_generated(subsequent, claiming, extra): + person, years, month = _blind_history( + subsequent=subsequent, + month=date(2013, 3, 1) if claiming else None, + ) + years[1974] = i.CoverageYear( + OBSERVED, + qc_quarters=tuple(q < extra for q in range(4)), + ) + blind = _classification( + replace(person, statutory_blindness=True), years, month + ) + if blind is not None: + _row(person, years, month) + + +@pytest.mark.parametrize( + "credit_gap", (9, 15), ids=("ordinary_window", "prior_needed") +) +@pytest.mark.parametrize( + "birth_year,onset_year", + ((1890, 1954), (1900, 1964), (1910, 1974), (1912, 1976)), +) +def test_unchanged_joint_proof_keeps_pre1913_male_blind_prior_attack( + birth_year, onset_year, credit_gap +): + """An insured pre-FRA prior keeps twenty old QCs current again. + + The 1890 case is a pre1956 control, outside the joint-proof branch. + For the others, earlier blindness is an additional legal basis for + the same first prior; the ordinary twenty-credit route is also proved. + """ + start = date(onset_year - credit_gap + 5, 1, 1) + end = date(onset_year - 1, 12, 31) + # At the prior start the immediately preceding twenty quarters all + # carry a QC, meeting 20/40. Add an older QC where the independent + # male fully prerequisite exceeds twenty (the 1912 cohort). + elapsed = max(6, min(40, start.year - 1951)) + assert elapsed <= 24 + person = _person( + birth=date(birth_year, 2, 2), + sex=i.Sex.MALE, + disability_onset=date(onset_year, 1, 15), + current_disability_period_end=date(onset_year, 12, 31), + prior_disability_periods=(i.DisabilityPeriod(start, end),), + ) + month = date(max(1968, onset_year + 1), 1, 1) + counts = {year: 4 for year in range(onset_year - credit_gap, start.year)} + if elapsed > 20: + counts[1951] = elapsed - 20 + years = history(person, month, counts) + known = _row(person, years, month, test=i.InsuredTest.DISABILITY) + assert known.unsupported is None + assert known.result.disability.insured + assert known.result.disability.qc_count_lower == 20 + assert known.result.disability.required == 20 + unknown = replace( + person, + prior_disability_periods=(), + prior_disability_periods_provenance=UNKNOWN, + ) + _row(unknown, years, month, test=i.InsuredTest.DISABILITY) + + +def test_six_qc_special_prior_attack_keeps_unknown_row(): + """Six recent QCs for a special prior still satisfy its fully floor. + + A blind prefix first insures six QCs in 1973. The 1976 special prior + uses six recent QCs, then permits the 1995 subsequent-special period. + Six is fewer than twenty, but does not waive fully insured status. + """ + person, years, month = _blind_history(subsequent=True) + observed = replace( + person, + prior_disability_periods_provenance=OBSERVED, + prior_disability_periods=( + i.DisabilityPeriod(date(1973, 4, 1), date(1975, 12, 31)), + i.DisabilityPeriod( + date(1976, 1, 1), date(1994, 12, 31), special_insured=True + ), + ), + ) + row = _row(observed, years, month, test=i.InsuredTest.DISABILITY) + assert row.unsupported is None + assert row.result.disability.insured + assert row.result.disability.rule == "subsequent_special" + assert row.result.disability.qc_count_lower == 6 + assert row.result.disability.required == 6 + assert row.result.disability.fully_qc_count_lower == 7 + assert row.result.disability.fully_required == 6 + _row(person, years, month, test=i.InsuredTest.DISABILITY) + + +def _simplified_prior_basis(flag=None): + """A deliberately inadmissible aggregate disability-prior basis.""" + person = _person( + birth=date(1926, 2, 2), + disability_onset=date(1989, 1, 15), + current_disability_period_end=date(1989, 12, 31), + prior_disability_periods=(), + prior_disability_periods_provenance=UNKNOWN, + conditions=() if flag is None else (flag,), + ) + month = date(1990, 1, 1) + years = history( + person, + month, + {1964: 4, 1965: 4, 1966: 4, 1967: 2, 1987: 4, 1988: 2}, + ) + years[1950] = i.CoverageYear( + OBSERVED, + quarterly_wages=( + Fraction(1200), + Fraction(0), + Fraction(0), + Fraction(0), + ), + ) + return person, years, month + + +def test_unchanged_simplified_prior_basis_does_not_insure_disability(): + """RS 00301.315 B.1 excludes this ordinary-to-aggregate conversion.""" + person, years, month = _simplified_prior_basis() + _invalid(person, years, month, test=i.InsuredTest.DISABILITY) + + +def test_unchanged_declared_simplified_prior_basis_keeps_named_refusal(): + """A fully-route declaration retains its unadjudicated specialist flag.""" + person, years, month = _simplified_prior_basis( + i.CoverageCondition.SIMPLIFIED_PRE1951, + ) + _refusal( + person, + years, + month, + i.InsuredUnsupportedReason.SIMPLIFIED_PRE1951, + test=i.InsuredTest.DISABILITY, + ) diff --git a/tests/test_track_b_insured_status_status_oracle.py b/tests/test_track_b_insured_status_status_oracle.py new file mode 100644 index 000000000..bc230986b --- /dev/null +++ b/tests/test_track_b_insured_status_status_oracle.py @@ -0,0 +1,272 @@ +"""Independent bounded status-completion oracle on invented declarations. + +Verification class: statutory conformance; no population, behavioral or +forecast claim. This oracle calls only public declaration and result APIs. +Its arithmetic does not import production quarter, assignment, clock, +requirement, witness or period-construction helpers. + +Space: women born February 2, 1960, ordinary or blind; no flags, no prior +or one known nonspecial prior, known current ending, and annual direct QCs +in 1990, 1995-2000 and 2002. The claiming-age variant adds four QCs in each +of 2003-2006. Every annual placement and both all-prior treatments are +enumerated. At most 576 placements, two establishment treatments and two +status treatments occur per declaration. Queries include the year after +the ending, four years after it and claiming age 62. No UNKNOWN earnings, +unknown periods, pre1978 credits, male transition, subsequent-special, +pre1956 alternate, death, continuing or unknown ending is claimed. + +Act 214(a), 223(c), 20 CFR 404.110(c), 404.130(a),(e),(f), 404.131, +404.143(b), 404.146(d) and 404.321(a) supply the arithmetic. Annual QCs +are assigned favorably (RS 00301.230). A lawful filling has its own first +insured start; that start supplies the current period for FULLY and +CURRENTLY. DISABILITY must qualify without using the period it establishes. +Each returned status must equal the favorable Boolean over all lawful +fillings. A named refusal retains the declaration and passes the oracle. +""" + +from dataclasses import dataclass +from datetime import date +from functools import cache +from itertools import combinations, product + +import pytest +from hypothesis import example, given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as rule +from populace_dynamics.track_b.gross_benefits import InvalidFamilyInput + + +@dataclass(frozen=True) +class Declaration: + blind: bool = False + prior: str = "overlap" + prior_count: int = 2 + onset_count: int = 1 + query: str = "later" + + @property + def month(self): + return { + "after": date(2003, 1, 1), + "later": date(2006, 1, 1), + "claiming": date(2022, 3, 1), + }[self.query] + + @property + def annual(self): + counts = { + 1990: 1, + 1995: 4, + 1996: 4, + 1997: 4, + 1998: 4, + 1999: self.prior_count, + 2000: self.onset_count, + 2002: 1, + } + if self.query == "claiming": + counts.update(dict.fromkeys(range(2003, 2007), 4)) + return counts + + @property + def periods(self): + if self.prior == "none": + return () + end = date(1999, 12, 31) + if self.prior == "overlap": + end = date(2000, 1, 31) + return ((date(1999, 1, 1), end),) + + +def quarter(day): + return day.year * 4 + (day.month - 1) // 3 + + +def _usable(credits, at, periods): + """404.146(d): retain credited endpoints, remove strict interiors.""" + return { + credit + for credit in credits + if credit <= at + and not any(quarter(a) < credit < quarter(b) for a, b in periods) + } + + +def _fully_requirement(at, periods): + # February 2, 1960 attains 21 in 1981 and 62 in 2022. + elapsed = sum( + not any(a.year <= year <= b.year for a, b in periods) + for year in range(1982, min(at // 4, 2022)) + ) + return max(6, min(40, elapsed)) + + +def _recent(usable, at, periods, length): + """404.130(f): count back, keeping credited endpoint quarters.""" + seen = count = 0 + cursor = at + while seen < length: + excluded = any( + quarter(a) <= cursor <= quarter(b) and cursor not in usable + for a, b in periods + ) + if not excluded: + seen += 1 + count += cursor in usable + cursor -= 1 + return count + + +def _disability(credits, at, periods, blind): + usable = _usable(credits, at, periods) + fully = len(usable) >= _fully_requirement(at, periods) + return fully and (blind or _recent(usable, at, periods, 40) >= 20) + + +def _all_placements(annual): + options = [ + tuple(combinations(range(year * 4, year * 4 + 4), count)) + for year, count in annual.items() + ] + for pieces in product(*options): + yield frozenset(credit for piece in pieces for credit in piece) + + +@cache +def favorable_statuses(case): + """Exhaust every filling before comparing to a public result.""" + answer = [False, False, False] + lawful = 0 + starts = set() + onset = date(2000, 2, 15) + ending = date(2002, 12, 31) + at = quarter(case.month) + for credits in _all_placements(case.annual): + # A declared nonspecial prior can rest on historical blindness. + # Here even its unexcluded ordinary fully requirement is met. + if case.periods and not _disability( + credits, quarter(case.periods[0][0]), (), True + ): + continue + treatments = (True, False) if case.periods else (False,) + for use_prior in treatments: + establishment_periods = case.periods if use_prior else () + first = next( + ( + candidate + for candidate in range(quarter(onset), quarter(ending) + 1) + if _disability( + credits, candidate, establishment_periods, case.blind + ) + ), + None, + ) + if first is None or any( + quarter(a) <= first <= quarter(b) for a, b in case.periods + ): + continue + lawful += 1 + starts.add(first) + year, q = divmod(first, 4) + start = ( + onset if first == quarter(onset) else date(year, 3 * q + 1, 1) + ) + completed = case.periods + ((start, ending),) + for status_periods in (completed, ()): + usable = _usable(credits, at, status_periods) + answer[0] |= len(usable) >= _fully_requirement( + at, status_periods + ) + answer[1] |= _recent(usable, at, status_periods, 13) >= 6 + # The first insured start is itself a valid 404.131 witness. + # Later queries do not erase that witness, and the current + # period is never used to establish its own DISABILITY status. + answer[2] |= any( + _disability(credits, q, establishment_periods, case.blind) + for q in range(quarter(onset), at + 1) + ) + return tuple(answer), lawful, tuple(sorted(starts)) + + +def _check(case): + expected, lawful, starts = favorable_statuses(case) + observed = rule.EarningsProvenance.OBSERVED + person = rule.Person( + date(1960, 2, 2), + sex=rule.Sex.FEMALE, + statutory_blindness=case.blind, + disability_onset=date(2000, 2, 15), + current_disability_period_established=True, + current_disability_period_provenance=observed, + current_disability_period_end=date(2002, 12, 31), + current_disability_period_end_provenance=observed, + prior_disability_periods=tuple( + rule.DisabilityPeriod(a, b) for a, b in case.periods + ), + prior_disability_periods_provenance=observed, + sspa211_applies=False, + sspa211_provenance=observed, + ) + years = { + year: ( + rule.CoverageYear(observed, qc_count=case.annual.get(year, 0)) + if year >= 1978 + else rule.CoverageYear(observed, qc_quarters=(False,) * 4) + ) + for year in range(1960, case.month.year + 1) + } + try: + result = rule.insured_status(person, years, case.month) + except rule.InsuredConfigurationUnsupported: + return "refused" + except InvalidFamilyInput as error: + if lawful: + pytest.fail(f"lawful status completion rejected: {case}: {error}") + return "invalid" + assert lawful, (case, "computed an impossible establishment", result) + actual = tuple( + getattr(result, name).insured + for name in ("fully", "currently", "disability") + ) + assert actual == expected, (case, actual, expected, starts, result) + return "computed" + + +def test_status_oracle_review_completion_has_favorable_fully_status(): + case = Declaration() + expected, lawful, starts = favorable_statuses(case) + assert lawful and 2000 * 4 + 1 in starts + assert expected[0] + _check(case) + + +@pytest.mark.parametrize("blind", (False, True)) +@pytest.mark.parametrize("prior", ("none", "clear", "overlap")) +@pytest.mark.parametrize("query", ("after", "later", "claiming")) +@pytest.mark.parametrize("prior_count", (2, 3)) +def test_status_oracle_completion_lattice(blind, prior, query, prior_count): + outcome = _check(Declaration(blind, prior, prior_count, 1, query)) + if prior == "none": + assert outcome == "computed" + + +@settings(max_examples=24, deadline=None, derandomize=True) +@example( + blind=False, + prior="overlap", + prior_count=2, + onset_count=1, + query="later", +) +@given( + blind=st.booleans(), + prior=st.sampled_from(("none", "clear", "overlap")), + prior_count=st.integers(2, 3), + onset_count=st.integers(1, 2), + query=st.sampled_from(("after", "later", "claiming")), +) +def test_status_oracle_generated_status_coherence( + blind, prior, prior_count, onset_count, query +): + _check(Declaration(blind, prior, prior_count, onset_count, query)) diff --git a/tests/tier_counts.json b/tests/tier_counts.json index ab0dc861c..afcddd004 100644 --- a/tests/tier_counts.json +++ b/tests/tier_counts.json @@ -1,7 +1,7 @@ { "schema_version": 1, "counts": { - "unit": 21140, + "unit": 21273, "artifact": 4271, "integration_psid": 1471, "reproduction_legacy": 520, From c28bb1dd4b1463191edcc0a95f2c33e44479466a Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sat, 31 Oct 2026 22:01:05 -0400 Subject: [PATCH 21/46] Refuse a decisive aggregate and tie each status to its own start (#562) The session attacked round 14 and found two defects. Round 14 left a decisive pre-1951 aggregate as an input error or as a false DISABILITY answer, citing RS 00301.315 B.1. Act 216(i)(3)(A), 223(c)(1)(A) and 404.132 reach the disability prerequisite through section 214, and filing facts stay unmodeled, so the rule now refuses by name wherever the aggregate could decide DISABILITY, the established period, its first start or the date last insured. Raw wages never turn a row into an input error, and simplified credits never count toward the recent rule. Each status and the established start placed annual QCs separately, so a status could rest on a placement that contradicts the reported start. Random invented declarations found 13 such answers in 28,000. Flexible credits now bound every filling at each possible start, and a search looks for a filling that attains the result with the reported start as its own. Otherwise the row refuses by name. The check joins each status to the start, not the statuses to one another. Mutation survivors then found a class the stress had missed: an entitlement month ends a CURRENTLY window before the onset, so a back-edge year can want its QC early for the status and late for the start. ENTITLEMENT_CONFLICTS pins one declaration per line of _start_sensitive_years. The stress test gained entitlement months, under-31 rows and a start-carrying assertion. All 21 mutations die. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 170 ++++- .../track_b_insured_status_mutations.json | 590 +++++++++++++++- .../track_b/insured_status.py | 445 ++++++++++-- tests/README-tiers.md | 4 +- ...est_track_b_insured_status_fix_round_14.py | 14 +- ...est_track_b_insured_status_fix_round_15.py | 639 ++++++++++++++++++ ...test_track_b_insured_status_fix_round_2.py | 21 +- ...st_track_b_insured_status_status_stress.py | 397 +++++++++++ tests/tier_counts.json | 2 +- 9 files changed, 2203 insertions(+), 79 deletions(-) create mode 100644 tests/test_track_b_insured_status_fix_round_15.py create mode 100644 tests/test_track_b_insured_status_status_stress.py diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index c26f553d5..597b8f5d4 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -662,13 +662,13 @@ input. An input error propagates and creates no row. | Medicare-qualified government employment | `medicare_government_employment_unsupported` | | Earned-basis wages or pre1956 alternate disability | `earned_basis_unsupported`, `disability_before_1956_unsupported` | | Fiscal or short taxable-year public declaration | `fiscal_taxable_year_unsupported`, `short_taxable_year_unsupported` | -| Supplied pre1951 wages, or UNKNOWN pre1951 years, could make a failed fully insured test pass under the simplified method; also an explicit specialist declaration | `simplified_pre1951_unsupported` | +| Supplied pre1951 wages, or UNKNOWN pre1951 years, could make a failed fully insured test pass under the simplified method, including the fully insured prerequisite of DISABILITY, the current period, its first start and the date last insured; also an explicit specialist declaration | `simplified_pre1951_unsupported` | | Positive raw1937 earnings needing half-year/age65 rules | `1937_earnings_allocation_unsupported` | | Separate pre1955 agricultural annual wages | `pre1955_agricultural_allocation_unsupported` | | Pre1951 self-employment income | `pre1951_self_employment_unsupported` | | Earnings require an increment after 2027 | `qc_amount_year_unsupported` | | Query before 1968; blind query before 1973; subsequent-special query before May 1983 | `entitlement_before_1968_unsupported`, `blindness_before_1973_unsupported`, `subsequent_special_before_1983_unsupported` | -| More than 4,096 disability-boundary combinations, or unresolved ordinary-establishment overlap requiring more than 4,096 credit fillings, after fixed overlap and every credit-count proof applicable to the surviving flag classes and foreign-credit declaration | `disability_boundary_assignments_unsupported` | +| More than 4,096 disability-boundary combinations, unresolved ordinary-establishment overlap requiring more than 4,096 credit fillings, or a first start that placement or prior treatment can move with no one filling supporting the returned result, after fixed overlap and every credit-count proof applicable to the surviving flag classes and foreign-credit declaration | `disability_boundary_assignments_unsupported` | The round-3 observable-trigger audit covers every `CoverageCondition`. An explicit condition continues to refuse under its own reason when the @@ -840,7 +840,7 @@ to a statutory sentence that does not state it. | --- | --- | | B1. UNKNOWN annual ordinary QCs range from zero through four, reduced by assignable birth/query/death/exit quarters. Deferred raw-conversion rows use their feasible minimum/maximum fillings only for establishment possibility. Exact annual amounts are monotone in earnings; every calendar year stays in 0–4. | B404.143: "we cannot credit you with more than four QCs for any calendar year"; A213(a)(2)(B)(vi) prohibits duplicate calendar-quarter QCs; B404.146 excludes unbegun/death quarters. Birth/exit are supplied-record premises. Additional-credit regimes retain refusal and cannot escape this bound through an ordinary result. Deferred rows still raise their original conversion refusal after a valid possibility survives; no temporary filling is exposed as a computed status. | | B2. Ordinary fully insured requirements lie in 6–40 and exclude only established disability years. Every elapsed-year endpoint uses its relevant candidate year and the historical sex/cohort rule. | B404.110(b)(1), (b)(2), (c), .132; A214(a) says "not counting ... any year any part of which was included in a period of disability". Medical onset without establishment cannot freeze years. Deemed/transitional alternatives are refused before using the ordinary requirement as universal. | -| B3. A simplified-pre1951 possibility uses the smallest known freeze requirement, or six for unresolved establishment/history, and maximum post1950 ordinary credits without exclusions. UNKNOWN pre1951 raw wages remain potentially decisive. | A213(c) grants "one quarter of coverage for each $400" subject to resulting fully insured status; B404.110(c)-(d); RS .315 B.1-B.2 record alternate historical/application conditions. This is an over-approximation for refusal, not a computed deemed-credit answer. A favorable ordinary witness with a higher requirement cannot narrow it. | +| B3. A simplified-pre1951 possibility uses the smallest known freeze requirement, or six for unresolved establishment/history, and maximum post1950 ordinary credits without exclusions. UNKNOWN pre1951 raw wages remain potentially decisive. DISABILITY compares the same bound at each quarter where the recent rule holds or blindness removes it. | A213(c) grants "one quarter of coverage for each $400" subject to resulting fully insured status; B404.110(c)-(d); RS .315 B.1-B.2 record alternate historical/application conditions. This is an over-approximation for refusal, not a computed deemed-credit answer. A favorable ordinary witness with a higher requirement cannot narrow it. | | B4. An alternate-pre1956 possibility uses maximum feasible QCs and an eligible 1952Q3–1955Q4 start with at least 20 total QCs and at least six continuous credited clock quarters, under favorable all-period use or disregard. It survives unless lower credits establish 20/40 in U10's shared disabled-quarter scan. | RS .480 A requires "at least 20 quarters of coverage" and "all quarters beginning with 03/51 ... are QCs", with "at least six"; B.1 permits the first freeze day 07/01/52 through 12/31/55. RS .132 B.2 applies prior-period exclusions to the continuous alternate clock, retaining credited beginning/ending quarters; C.2 requires all periods used or all disregarded. Candidate starts obey I8/I14's latest permissible horizon, so recovery before July 1952 cannot be rescued by the first alternate start. Exclusion instead obeys U10's earliest shared date, including the two-month offset for declared ends and continuity. A lower-credit ordinary 20/40 witness in that shared interval removes the route for all credit fillings; an upper-only or later witness preserves the named refusal. Unmodeled application conditions can remove candidates but do not prove an input error. An explicit `DISABILITY_BEFORE_1956` flag adds no route beyond this check. A fully-route flag may rely on this same alternate possibility when its ordinary recent rules fail; neither flag adjudicates the alternate's application conditions. | | B5. Universal recent, fully-prerequisite, and annual count envelopes use zero through maximum feasible ordinary lifetime/year QCs whenever unknown periods/earnings can switch witnesses. | A213(a)(2)(B)(vi) prohibits double credit; B404.146(d) excludes interiors unless disregarded. Every concrete ordinary assignment is a subset of feasible unique lifetime quarters. The envelope permits every witness, even when adding QCs switches to a lower-count witness. Specialist possibilities remain refusals. | | B6. With known earnings and an UNKNOWN ending, returned count bounds include all end-candidate counts admitted by continuity; with entirely known facts they remain exact. | B404.120(b), .130(f), .146(d) distinguish credited endpoints and excluded interiors. All candidate quarters are enumerated, including early endpoints and capped-FRA candidates, subject to any continues-through observation; extrema therefore cover each completion. A continuity date is never inserted as a credited endpoint. No monotonic endpoint-count premise is used. | @@ -854,6 +854,7 @@ to a statutory sentence that does not state it. | B14. Declaring continuity never widens the administrative-end candidate set; every returned status and count envelope remains valid for every retained concrete ending. | C321(c)'s ending events still govern. Set intersection with ends on/after the observation can only remove candidates; it creates neither an ending nor a new credit. The universal envelope remains unchanged where other unknown facts require it. | | B15. Ordinary establishment overlap resolution enumerates at most 4,096 unknown-credit fillings after its fixed-date monotonicity, candidate-quarter, six-QC, and minimum-requirement proofs. | C320(b)(2) and C321(a) require one insured beginning consistent with the complete declaration. I13 settles fixed-quarter overlap and I15 settles a known-history nonblind lifetime-QC shortfall before enumeration. If neither settles the declaration, a search beyond the limit returns `disability_boundary_assignments_unsupported`; it asserts neither a concrete filling nor an input error. | | B16. A deferred raw-conversion row retains independently computable ordinary credits in its minimum and every enumerated filling, and cannot exceed feasible calendar-quarter credits in its maximum. | A213(d)(2)'s prior-increment floor bounds future annual credits above by the captured 2027 increment applied to the supplied wages plus SE income; the possibility-only lower bound is zero. Raw 1937 allocation remains zero through four because A213(b)'s half-year rule is unresolved. For separate pre1955 agriculture or pre1951 SE, supported quarterly wage credits and supported post1950 calendar-year SE credits remain fixed; unresolved additional allocation can fill only remaining allowed quarters. Both minimum and maximum fillings may violate derived overlap even when a middle filling is valid, so neither endpoint alone proves impossibility. These bounds do not adjudicate a specialist allocation or replace its refusal. | +| B17. The first-start check refuses when flexible credits allow a better result at any possible start, and it searches at most 4,096 placements of the annual years that can change a first insured quarter. | 404.321(a) gives a record one start, and RS .230 makes placement flexible. A year wholly inside every tested window and untouched by a period adds its full count wherever its QCs fall, so it stays flexible. Without prior periods, an insured worst filling proves no filling starts later, and the check stops. The bound can refuse a declaration that no concrete filling improves, and a search can reach its limit before it attains a result. Both return `disability_boundary_assignments_unsupported`, so the row keeps its weight; neither asserts a filling or an input error. | The round-5 adversarial audit revisits each row in both directions in `scratch/review/round5-premise-audit.md`: a valid filling cannot be rejected, @@ -1827,18 +1828,8 @@ rather than the retirement calendar in 404.110(b), governs a prior that must begin before FRA. An attempted aggregate-funded blind prior was also executed and minimized. -It is not a proved lawful no-flag completion: RS 00301.315 B.1 expressly -says, "The simplified method does not apply to disability claims." The -general incorporation of 404.110 by 404.132, including the aggregate method -in paragraph (d), suggests a broader alternative reading. The default -follows the explicit disability-specific POMS exclusion. The existing -`SIMPLIFIED_PRE1951` declared condition represents the alternative as a -named refusal without adjudicating its basis or computing a disability -period from aggregate credits. The two public controls are -`test_unchanged_simplified_prior_basis_does_not_insure_disability` and -`test_unchanged_declared_simplified_prior_basis_keeps_named_refusal`. -The report gives both source texts and the invented QC difference; no -payment is computed and no additional statutory approval is requested. +Round 14 left it an input error, following RS 00301.315 B.1. Round 15 +replaces that reading; the section below gives the sources. Eleven isolated implementation mutations were caught, including all ten requested rules and the additional canonical diagnostic tie rule. Exact @@ -1864,6 +1855,155 @@ disagreement are recorded in `scratch/review/fix-round-14-report.md`. DLI, raw earnings, UNKNOWN earnings/ends, foreign routes, and specialist flags are outside this oracle's claim. +## Round 15 the aggregate and each filling's own start + +Verification class: statutory conformance on invented declarations only. +This correction admits no population, behavioral, payment, or forecast claim. +Session checks found both defects after round 14, before the next review. + +### The pre-1951 aggregate on disability routes + +Act 223(c)(1)(A) and Act 216(i)(3)(A) each ask whether "he would have been +a fully insured individual" under section 214. Act 213(c) applies "For +purposes of sections 414(a) and 415(d)". Section 404.132 says "we use the +fully insured status requirements in § 404.110, but apply the following +rules in determining when the period of elapsed years ends", and 404.110(d) +is one of those requirements. RS 00301.315 B.1 alone says, "The simplified +method does not apply to disability claims." The statute and the regulation +therefore reach the disability prerequisite (P1, P2). Filing facts stay +unmodeled, so the rule credits no deemed quarter. It refuses by name where +the aggregate could decide an answer, and it never rejects such a +declaration or answers it false. A row that a defensible reading keeps +stays a row. Source conflict +`us:oasdi-insured-simplified-pre1951-disability-scope`. + +The executed record is an invented woman born 1926-02-02 with $2,400 in the +first quarter of each of 1948, 1949 and 1950, 22 later QCs and onset on +1989-01-15. She has 25 ordinary QCs, or 40 with the aggregate, against 37 +required. At round 14, FULLY refused by name, DISABILITY computed false, and +an established period raised `InvalidFamilyInput`. All three now retain the +row with `simplified_pre1951_unsupported`. The boundary is exact: $6,000 in +total gives 15 + 22 = 37 and refuses, and $5,997 gives 14 + 22 = 36 and +computes false. The aggregate also reaches a first start that an ordinary +credit would otherwise date later, and a date last insured that ordinary +fully insured status would otherwise end sooner. Blindness removes the +recent rule here as elsewhere. Simplified credits never count toward the +recent rule, because 404.110(d) applies "For purposes of paragraph (b) of +this section". A true ordinary status stays computed. + +An UNKNOWN-history declaration whose only fully insured route for a prior +is the aggregate now keeps its row under +`unknown_prior_disability_periods_decide_status`. The automatic aggregate +acts as a fully-route condition in the establishment proofs, so its +six-QC floor and recent-rule scan match the declared flag. + +### One filling carries its own start + +Each status places annual QCs favorably for its own window, and the +established start does the same (RS 00301.230). Round 14 stopped those +placements from mixing only where the favorable start overlapped a prior. +Random invented declarations found the same mix without overlap, and with +no prior at all. A woman born 1956-02-02 has annual QCs 1987:2, 1988:4, +1989:3, 1990:4, 1991:4, 1992:2 and 1994:1, onset 1992-01-15, and a period +ending 1994-09-30. The 1994 QC must sit in the first insured quarter, so at +most two later quarters leave the 13-quarter window and CURRENTLY finds at +most five of the six QCs at 1995-01-01 in every lawful filling. The rule +took its start from 1994Q1, moved the same QC to 1994Q4 for CURRENTLY, and +answered true. + +404.321(a) gives one record one start, and that period's exclusions then +shape FULLY, CURRENTLY and the date last insured. Where annual placement or +prior treatment can move the start, the returned result stands only if one +filling attains it with the reported start as its own, and no filling can +improve on it. +`_settle_first_start` checks the second condition first. Flexible credits +bound every filling at each possible start, so a bound that allows a better +status or a later date last insured refuses the row with +`disability_boundary_assignments_unsupported`. It then looks for an +attaining filling, starting from the filling that insures the reported +start and varying the latest years first, because those years conflict +with the later windows. The first attaining filling ends the search. A year +that can't move the start stays flexible, so each status still places it +favorably. The check joins each status to the start, not the statuses to one +another. This keeps the favorable answer of RS 00301.230 and replaces an +answer no single record supports. + +A status window can also end before the onset. `_events` tests CURRENTLY at +a declared RIB or DIB entitlement month, so a year at the back edge of a +recent-rule window can want its QC early for the status and late for the +start. An invented woman born 1960-02-02 has annual QCs 1990:4, 1991:4, +1998:3, 1999:2, 2000:1, four in each of 2001 to 2004, and 2005:3, onset +2010-01-15 and a DIB entitlement month of 2000-01. The 2000 QC reaches the +20 of 40 at the onset only in 2000Q2 or later, and it reaches six of 13 at +the entitlement month only in 2000Q1. No filling holds both, so the row +refuses, and the same record without the entitlement month computes false. +`_start_sensitive_years` keeps the 40-quarter and 12-quarter back edges, the +age-21 edge and prior-period years enumerated for this reason. A filling +whose own start falls later can also hold the status, and it doesn't count: +the search requires the reported start. `ENTITLEMENT_CONFLICTS` in +`tests/test_track_b_insured_status_fix_round_15.py` pins one declaration for +each of those lines. + +The bound refuses without enumerating, so it can refuse a declaration that +no concrete filling improves. That direction is deliberate: the row keeps +its weight under a named refusal, and proving every filling false would +cost far more than the row gives back. Bound B17 records the limit. + +### Status stress oracle and bounds + +`tests/test_track_b_insured_status_status_stress.py` widens the status +oracle with the same plain arithmetic. Births run from 1940 to 1979, and +ages at onset from 31 to 58. Onsets start in 1992. Endings, queries, +annual totals with at most four partial years, and no prior, a clear prior +or an overlapping prior vary by seed, and blindness holds in a quarter of +cases. The session ran 28,000 such declarations at round 14's head. It +found 13 status disagreements and no false rejection, and each of the 13 +had more than one possible first start. The committed test pins all 13 +seeds and generates more. Two more generators add a DIB entitlement month, +drawn mostly from partial years up to the onset, and ages 22 to 30 at onset +under 404.130(c) and (d). DLI, the subsequent-special route, UNKNOWN facts +and flags stay outside its claim. Declared priors are not re-adjudicated. + +After the fix, the same 28,000 and 14,000 fresh declarations give no +disagreement, no false rejection and no computed row without a lawful +filling. On the 28,000, rows refused by name that have a lawful filling +rise from 435 to 562. Thirteen of the 127 are the disagreements. The other +114 computed agreeing answers at round 14, and they are the cost of the +loose bound: about 1% of computed rows, in a space drawn to hold partial +years. Rejected rows stay at 15,785. + +Five surviving mutations then showed the generator had never drawn an +entitlement month or an under-31 row. The session widened the oracle with +both, and it added a stricter check: each true status must hold on a filling +whose own first start is the reported start. Across 14,000 declarations with +a DIB entitlement month and 14,000 under-31 declarations, 18,754 rows computed +and agreed, 349 refused by name with a lawful filling, and 8,894 raised +`InvalidFamilyInput` with no lawful filling. Nothing disagreed, and no status +lacked its start. One row the oracle called lawful raised +`InvalidFamilyInput`. It ends a period in December 1980, the month of its +onset, so 404.321(b)'s implied recovery precedes the onset on every filling. +The oracle doesn't model that rule, and the committed generator starts +onsets in 1981. + +The invariants added in this round are executed by these tests: + +- every computed status equals the favorable Boolean over lawful fillings, + each carried through its own start + (`test_status_stress_matches_the_favorable_filling`, + `test_status_stress_with_an_entitlement_month`, + `test_status_stress_under_31`, and the status oracle's declarations); +- a reported start is the start of a filling that attains the result, and + each true status holds on a filling with that start (the same three + properties, `test_status_stress_refuses_a_start_no_filling_supports`, + `test_a_moving_start_keeps_a_result_one_filling_attains`, + `test_an_entitlement_window_cannot_borrow_the_starts_placement`); +- raw pre-1951 wages never turn a row into an input error + (`test_pre1951_wages_only_add_rows`); +- a refused FULLY and a met recent rule never compute DISABILITY false + (`test_fully_refusal_and_a_met_recent_rule_never_compute_false`); +- the DISABILITY refusal tracks the exact aggregate + (`test_disability_refusal_tracks_the_exact_aggregate`). + ## Not in scope No real data, population evaluation, baseline claiming hazard, behavioral diff --git a/docs/design/track_b_insured_status_mutations.json b/docs/design/track_b_insured_status_mutations.json index b9d5713b3..0a4d7419c 100644 --- a/docs/design/track_b_insured_status_mutations.json +++ b/docs/design/track_b_insured_status_mutations.json @@ -4723,11 +4723,595 @@ "round_14_runner_source": "\"\"\"Run named invented-data conformance tests with open-event auditing.\"\"\"\n\nimport hashlib\nimport json\nimport os\nfrom pathlib import Path\nimport sys\n\nCOUNTS = {\"restricted_opens\": 0, \"subprocess.Popen\": 0, \"os.system\": 0}\nBARRED = {\n \"gates.yaml\", \"adjusted_poverty.py\", \"rows.py\",\n \"ssa_trust_fund_interest_rates_2026.json\",\n \"urban2010_cola_comparison.md\", \"urban2010_fra68_comparison.md\",\n \"boomers2004_uniform_cut_comparison.md\", \"minimum_benefits_comparison.md\",\n \"m6_projection_engine.md\", \"mint8_table_user_guide.source.html\",\n \"test_anchor_provenance_erratum.py\",\n}\n\n\ndef audit(event, arguments):\n if event == \"open\" and isinstance(arguments[0], (str, bytes)):\n path = os.fsdecode(arguments[0])\n name = Path(path).name\n if (\n name in BARRED\n or name.startswith((\"adjusted_poverty.\", \"rows.\"))\n or \"/PolicyEngine/psid-data/\" in path\n or \"/microcosm-launch-evidence/\" in path\n or \"/dynasim-refs/\" in path\n or \"/claude-501/\" in path\n ):\n COUNTS[\"restricted_opens\"] += 1\n raise RuntimeError(path)\n elif event in (\"subprocess.Popen\", \"os.system\"):\n COUNTS[event] += 1\n\n\ndef main():\n for name in (\"POPULACE_DYNAMICS_PSID_DIR\", \"POPULACE_DYNAMICS_EPUF_DIR\"):\n assert os.environ[name] == \"/nonexistent/trackb-round14\"\n assert sys.argv[1:]\n assert all(\n not argument.startswith(\"tests/\") or \".py\" in argument\n for argument in sys.argv[1:]\n )\n sys.addaudithook(audit)\n from populace_dynamics.track_b import insured_status as insured\n\n source_path = Path(insured.__file__)\n original = source_path.read_bytes()\n baseline_path = os.environ.get(\"TRACKB_ROUND14_SOURCE\")\n if baseline_path:\n baseline = Path(baseline_path).read_bytes()\n exec(compile(baseline, str(source_path), \"exec\"), insured.__dict__)\n print(\"BASELINE\", hashlib.sha256(baseline).hexdigest(), flush=True)\n spec_path = os.environ.get(\"TRACKB_ROUND14_MUTATION\")\n if spec_path:\n spec = json.loads(Path(spec_path).read_text())\n assert hashlib.sha256(original).hexdigest() == spec[\"source_sha256\"]\n source = original.decode()\n for change in spec[\"changes\"]:\n assert source.count(change[\"before\"]) == 1, change[\"before\"]\n source = source.replace(change[\"before\"], change[\"after\"], 1)\n exec(compile(source, str(source_path), \"exec\"), insured.__dict__)\n print(\"MUTATION\", spec[\"name\"], flush=True)\n import pytest\n\n try:\n return pytest.main(sys.argv[1:])\n finally:\n assert source_path.read_bytes() == original\n print(\"OPEN_AUDIT\", json.dumps(COUNTS, sort_keys=True), flush=True)\n\n\nif __name__ == \"__main__\":\n raise SystemExit(main())\n", "round_14_note": "All ten requested mutations and the canonical diagnostic tie mutation were killed by named public tests. Each run used nonexistent data roots, one thread per library, in-memory mutation only, unchanged implementation bytes, zero restricted opens and zero spawned-process audit events.", "round_14_test_sha256": { - "tests/test_track_b_insured_status_fix_round_14.py": "b3a75d40c6f7830d5afa3d930b700c981bf4e39d1f29d66b5d7ed1fa405484e7", - "tests/test_track_b_insured_status_classification_oracle.py": "9b04808e9eb81fc2d7ccc4835fffed84837900c11284bd278c8336a0ad2215d2", + "tests/test_track_b_insured_status_fix_round_14.py": "d8a39b3cbc638340ebfc7ce32dc4a91c4c226ed9d3b5dbcf4e171c6dee8077de", + "tests/test_track_b_insured_status_classification_oracle.py": "d3920af4bc75ec957b1d1b9e9f8c583428488ea8b116abb1fd35253d8c8bc898", "tests/test_track_b_insured_status_status_oracle.py": "4b603ca88ea6b52e518dcc93ef08d67ed49f7604aa1894a3b50baedf47aa2b61" }, "round_14_replay": "Write round_14_runner_source to scratch/review/run_round14_named.py. For each round_14_mutations record, write name/source_sha256/changes to its spec_path, then execute its exact command. Mutations apply only in memory.", "round_14_final_source_sha256": "677f7f812f92ac0b072265b7ea664d046986bcc92c21339140ff4dd737b28048", - "round_14_final_source_note": "Rewrapped two docstring lines after the mutation runs; code unchanged." + "round_14_final_source_note": "Rewrapped two docstring lines after the mutation runs; code unchanged.", + "round_15_mutations": [ + { + "name": "drop_disability_aggregate_refusal", + "source_sha256": "474239bd8216a942e55c462b43a441a23abc8b96ed820ddb02de53c60b266beb", + "changes": [ + { + "before": " if not lo[0] and any(\n _aggregate_could_insure(person, years, upper, event, exit_month)", + "after": " if False and any(\n _aggregate_could_insure(person, years, upper, event, exit_month)" + } + ], + "spec_path": "scratch/review/round15-mutation-drop_disability_aggregate_refusal.json", + "log": "scratch/review/round15-mutation-drop_disability_aggregate_refusal.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round15 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round15 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND15_MUTATION=scratch/review/round15-mutation-drop_disability_aggregate_refusal.json .venv/bin/python scratch/review/run_round15_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_status_oracle.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_15.py::test_blind_aggregate_decides_below_six_ordinary_qcs[amount0-True]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "drop_aggregate_fully_route", + "source_sha256": "474239bd8216a942e55c462b43a441a23abc8b96ed820ddb02de53c60b266beb", + "changes": [ + { + "before": " ) or _aggregate_establishment_possible(\n person, years, credits, horizon, exit_month\n )\n", + "after": " )\n" + } + ], + "spec_path": "scratch/review/round15-mutation-drop_aggregate_fully_route.json", + "log": "scratch/review/round15-mutation-drop_aggregate_fully_route.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round15 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round15 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND15_MUTATION=scratch/review/round15-mutation-drop_aggregate_fully_route.json .venv/bin/python scratch/review/run_round15_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_status_oracle.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_15.py::test_aggregate_keeps_the_established_period_row[InsuredTest.FULLY]", + "tests/test_track_b_insured_status_fix_round_15.py::test_aggregate_keeps_the_established_period_row[InsuredTest.DISABILITY]", + "tests/test_track_b_insured_status_fix_round_15.py::test_aggregate_keeps_the_established_period_row[InsuredTest.ALL]", + "tests/test_track_b_insured_status_fix_round_15.py::test_blind_established_period_keeps_the_aggregate_row", + "tests/test_track_b_insured_status_fix_round_15.py::test_unknown_prior_history_keeps_the_aggregate_row" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "drop_establishment_except_refusal", + "source_sha256": "474239bd8216a942e55c462b43a441a23abc8b96ed820ddb02de53c60b266beb", + "changes": [ + { + "before": " if _aggregate_establishment_possible(\n person,\n years,\n upper,\n _current_period_start_horizon(person, month),", + "after": " if False and _aggregate_establishment_possible(\n person,\n years,\n upper,\n _current_period_start_horizon(person, month)," + } + ], + "spec_path": "scratch/review/round15-mutation-drop_establishment_except_refusal.json", + "log": "scratch/review/round15-mutation-drop_establishment_except_refusal.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round15 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round15 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND15_MUTATION=scratch/review/round15-mutation-drop_establishment_except_refusal.json .venv/bin/python scratch/review/run_round15_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_status_oracle.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_15.py::test_aggregate_keeps_the_established_period_row[InsuredTest.FULLY]", + "tests/test_track_b_insured_status_fix_round_15.py::test_aggregate_keeps_the_established_period_row[InsuredTest.DISABILITY]", + "tests/test_track_b_insured_status_fix_round_15.py::test_aggregate_keeps_the_established_period_row[InsuredTest.ALL]", + "tests/test_track_b_insured_status_fix_round_15.py::test_blind_established_period_keeps_the_aggregate_row" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "drop_later_start_refusal", + "source_sha256": "474239bd8216a942e55c462b43a441a23abc8b96ed820ddb02de53c60b266beb", + "changes": [ + { + "before": " if lo_start is not None and any(\n _aggregate_could_insure(", + "after": " if False and any(\n _aggregate_could_insure(" + } + ], + "spec_path": "scratch/review/round15-mutation-drop_later_start_refusal.json", + "log": "scratch/review/round15-mutation-drop_later_start_refusal.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round15 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round15 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND15_MUTATION=scratch/review/round15-mutation-drop_later_start_refusal.json .venv/bin/python scratch/review/run_round15_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_status_oracle.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_15.py::test_aggregate_can_move_the_first_insured_start" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "drop_dli_aggregate_guard", + "source_sha256": "474239bd8216a942e55c462b43a441a23abc8b96ed820ddb02de53c60b266beb", + "changes": [ + { + "before": " if years is not None and _aggregate_could_insure(\n person, years, credits, at, exit_month, onset=False", + "after": " if False and _aggregate_could_insure(\n person, years, credits, at, exit_month, onset=False" + } + ], + "spec_path": "scratch/review/round15-mutation-drop_dli_aggregate_guard.json", + "log": "scratch/review/round15-mutation-drop_dli_aggregate_guard.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round15 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round15 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND15_MUTATION=scratch/review/round15-mutation-drop_dli_aggregate_guard.json .venv/bin/python scratch/review/run_round15_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_status_oracle.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_15.py::test_aggregate_can_extend_the_date_last_insured", + "tests/test_track_b_insured_status_fix_round_15.py::test_fully_refusal_and_a_met_recent_rule_never_compute_false" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "aggregate_boundary_strict", + "source_sha256": "474239bd8216a942e55c462b43a441a23abc8b96ed820ddb02de53c60b266beb", + "changes": [ + { + "before": "wages >= 400 and wages // 400 + post1950 >= required", + "after": "wages >= 400 and wages // 400 + post1950 > required" + } + ], + "spec_path": "scratch/review/round15-mutation-aggregate_boundary_strict.json", + "log": "scratch/review/round15-mutation-aggregate_boundary_strict.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round15 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round15 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND15_MUTATION=scratch/review/round15-mutation-aggregate_boundary_strict.json .venv/bin/python scratch/review/run_round15_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_status_oracle.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_15.py::test_disability_boundary_is_one_whole_400_credit[2000-True]", + "tests/test_track_b_insured_status_fix_round_15.py::test_disability_refusal_tracks_the_exact_aggregate", + "tests/test_track_b_insured_status_fix_round_15.py::test_blind_aggregate_decides_below_six_ordinary_qcs[amount0-True]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "aggregate_ignores_recent_rule", + "source_sha256": "474239bd8216a942e55c462b43a441a23abc8b96ed820ddb02de53c60b266beb", + "changes": [ + { + "before": " if not (\n person.statutory_blindness\n or _witness(\n person,\n credits,\n at,\n exit_month,\n InsuredTest.DISABILITY,\n onset=onset,", + "after": " if False and not (\n person.statutory_blindness\n or _witness(\n person,\n credits,\n at,\n exit_month,\n InsuredTest.DISABILITY,\n onset=onset," + } + ], + "spec_path": "scratch/review/round15-mutation-aggregate_ignores_recent_rule.json", + "log": "scratch/review/round15-mutation-aggregate_ignores_recent_rule.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round15 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round15 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND15_MUTATION=scratch/review/round15-mutation-aggregate_ignores_recent_rule.json .venv/bin/python scratch/review/run_round15_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_status_oracle.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_15.py::test_disability_boundary_is_one_whole_400_credit[1999-False]", + "tests/test_track_b_insured_status_fix_round_15.py::test_disability_refusal_tracks_the_exact_aggregate", + "tests/test_track_b_insured_status_fix_round_15.py::test_simplified_credits_never_count_toward_the_recent_rule", + "tests/test_track_b_insured_status_fix_round_15.py::test_unknown_prior_history_keeps_the_aggregate_row" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "remove_first_start_check", + "source_sha256": "474239bd8216a942e55c462b43a441a23abc8b96ed820ddb02de53c60b266beb", + "changes": [ + { + "before": " if lo_start is not None:\n kinds = tuple(", + "after": " if False:\n kinds = tuple(" + } + ], + "spec_path": "scratch/review/round15-mutation-remove_first_start_check.json", + "log": "scratch/review/round15-mutation-remove_first_start_check.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round15 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round15 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND15_MUTATION=scratch/review/round15-mutation-remove_first_start_check.json .venv/bin/python scratch/review/run_round15_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_status_oracle.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_15.py::test_no_filling_carries_the_start_and_the_status_together[InsuredTest.CURRENTLY]", + "tests/test_track_b_insured_status_fix_round_15.py::test_no_filling_carries_the_start_and_the_status_together[InsuredTest.ALL]", + "tests/test_track_b_insured_status_fix_round_15.py::test_the_date_last_insured_alone_can_refuse_a_moving_start", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.CURRENTLY-forty", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.CURRENTLY-later", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.CURRENTLY-prior", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.CURRENTLY-twelve", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.CURRENTLY-age", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.ALL-forty", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.ALL-later", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.ALL-prior", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.ALL-twelve", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.ALL-age", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[102037]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[102202]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[103045]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[103702]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[105793]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[109597]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[110777]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[203310]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[207027]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[207682]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[209481]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[209505]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[212010]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_matches_the_favorable_filling" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "drop_bound_refusal", + "source_sha256": "474239bd8216a942e55c462b43a441a23abc8b96ed820ddb02de53c60b266beb", + "changes": [ + { + "before": " if any(\n _improves(outcome, returned, last_insured)\n for outcome in _period_outcomes(", + "after": " if False and any(\n _improves(outcome, returned, last_insured)\n for outcome in _period_outcomes(" + } + ], + "spec_path": "scratch/review/round15-mutation-drop_bound_refusal.json", + "log": "scratch/review/round15-mutation-drop_bound_refusal.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round15 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round15 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND15_MUTATION=scratch/review/round15-mutation-drop_bound_refusal.json .venv/bin/python scratch/review/run_round15_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_status_oracle.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_15.py::test_the_date_last_insured_alone_can_refuse_a_moving_start", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[102037]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[102202]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[103045]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[105793]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[109597]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[110777]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[203310]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[207027]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[207682]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[209481]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[209505]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[212010]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_matches_the_favorable_filling" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "drop_unattained_refusal", + "source_sha256": "474239bd8216a942e55c462b43a441a23abc8b96ed820ddb02de53c60b266beb", + "changes": [ + { + "before": " return\n _refuse(\n InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY,\n \"First insured start depends", + "after": " return\n return\n _refuse(\n InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY,\n \"First insured start depends" + } + ], + "spec_path": "scratch/review/round15-mutation-drop_unattained_refusal.json", + "log": "scratch/review/round15-mutation-drop_unattained_refusal.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round15 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round15 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND15_MUTATION=scratch/review/round15-mutation-drop_unattained_refusal.json .venv/bin/python scratch/review/run_round15_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_status_oracle.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_15.py::test_no_filling_carries_the_start_and_the_status_together[InsuredTest.CURRENTLY]", + "tests/test_track_b_insured_status_fix_round_15.py::test_no_filling_carries_the_start_and_the_status_together[InsuredTest.ALL]", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.CURRENTLY-forty", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.CURRENTLY-later", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.CURRENTLY-prior", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.CURRENTLY-twelve", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.CURRENTLY-age", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.ALL-forty", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.ALL-prior", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.ALL-twelve", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.ALL-age", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[103702]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_matches_the_favorable_filling" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "drop_dli_comparison", + "source_sha256": "474239bd8216a942e55c462b43a441a23abc8b96ed820ddb02de53c60b266beb", + "changes": [ + { + "before": " dated=dli is not None and not prior_unknown,\n", + "after": " dated=False,\n" + }, + { + "before": " last_insured=(\n dli.upper if dli is not None and not prior_unknown else None\n ),\n", + "after": " last_insured=None,\n" + } + ], + "spec_path": "scratch/review/round15-mutation-drop_dli_comparison.json", + "log": "scratch/review/round15-mutation-drop_dli_comparison.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round15 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round15 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND15_MUTATION=scratch/review/round15-mutation-drop_dli_comparison.json .venv/bin/python scratch/review/run_round15_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_status_oracle.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_15.py::test_the_date_last_insured_alone_can_refuse_a_moving_start" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "reverse_worst_filling", + "source_sha256": "474239bd8216a942e55c462b43a441a23abc8b96ed820ddb02de53c60b266beb", + "changes": [ + { + "before": "chosen = vacant[-count:] if year == start.year else vacant[:count]", + "after": "chosen = vacant[:count] if year == start.year else vacant[-count:]" + } + ], + "spec_path": "scratch/review/round15-mutation-reverse_worst_filling.json", + "log": "scratch/review/round15-mutation-reverse_worst_filling.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round15 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round15 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND15_MUTATION=scratch/review/round15-mutation-reverse_worst_filling.json .venv/bin/python scratch/review/run_round15_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_status_oracle.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_15.py::test_no_filling_carries_the_start_and_the_status_together[InsuredTest.CURRENTLY]", + "tests/test_track_b_insured_status_fix_round_15.py::test_no_filling_carries_the_start_and_the_status_together[InsuredTest.ALL]", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.CURRENTLY-forty", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.CURRENTLY-later", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.CURRENTLY-twelve", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.CURRENTLY-age", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.ALL-forty", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.ALL-later", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.ALL-twelve", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.ALL-age", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[103702]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_matches_the_favorable_filling" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "start_fixed_ignores_priors", + "source_sha256": "474239bd8216a942e55c462b43a441a23abc8b96ed820ddb02de53c60b266beb", + "changes": [ + { + "before": " if person.prior_disability_periods:\n return False\n rows, _ = _world(person, credits, _qid(month), exit_month, False)\n worst = dict(credits)", + "after": " rows, _ = _world(person, credits, _qid(month), exit_month, False)\n worst = dict(credits)" + } + ], + "spec_path": "scratch/review/round15-mutation-start_fixed_ignores_priors.json", + "log": "scratch/review/round15-mutation-start_fixed_ignores_priors.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round15 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round15 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND15_MUTATION=scratch/review/round15-mutation-start_fixed_ignores_priors.json .venv/bin/python scratch/review/run_round15_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_status_oracle.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_15.py::test_the_date_last_insured_alone_can_refuse_a_moving_start", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[102202]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[105793]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[109597]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[203310]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[207027]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[207682]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[209481]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[209505]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_matches_the_favorable_filling" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "drop_front_edge_years", + "source_sha256": "474239bd8216a942e55c462b43a441a23abc8b96ed820ddb02de53c60b266beb", + "changes": [ + { + "before": " quarters.update(range(onset, last + 1))\n", + "after": "" + } + ], + "spec_path": "scratch/review/round15-mutation-drop_front_edge_years.json", + "log": "scratch/review/round15-mutation-drop_front_edge_years.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round15 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round15 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND15_MUTATION=scratch/review/round15-mutation-drop_front_edge_years.json .venv/bin/python scratch/review/run_round15_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_status_oracle.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_15.py::test_no_filling_carries_the_start_and_the_status_together[InsuredTest.CURRENTLY]", + "tests/test_track_b_insured_status_fix_round_15.py::test_no_filling_carries_the_start_and_the_status_together[InsuredTest.ALL]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[103702]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_matches_the_favorable_filling" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "drop_back_edge_years", + "source_sha256": "474239bd8216a942e55c462b43a441a23abc8b96ed820ddb02de53c60b266beb", + "changes": [ + { + "before": " quarters = set(range(onset - 39 - excluded, last - 38))\n", + "after": " quarters = set()\n" + } + ], + "spec_path": "scratch/review/round15-mutation-drop_back_edge_years.json", + "log": "scratch/review/round15-mutation-drop_back_edge_years.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round15 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round15 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND15_MUTATION=scratch/review/round15-mutation-drop_back_edge_years.json .venv/bin/python scratch/review/run_round15_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_status_oracle.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.CURRENTLY-forty", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.CURRENTLY-later", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.ALL-forty" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "drop_twelve_quarter_edge_years", + "source_sha256": "474239bd8216a942e55c462b43a441a23abc8b96ed820ddb02de53c60b266beb", + "changes": [ + { + "before": " quarters.update(range(onset - 11 - excluded, last - 10))\n", + "after": "" + } + ], + "spec_path": "scratch/review/round15-mutation-drop_twelve_quarter_edge_years.json", + "log": "scratch/review/round15-mutation-drop_twelve_quarter_edge_years.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round15 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round15 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND15_MUTATION=scratch/review/round15-mutation-drop_twelve_quarter_edge_years.json .venv/bin/python scratch/review/run_round15_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_status_oracle.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.CURRENTLY-twelve", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.ALL-twelve" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "drop_age21_edge_year", + "source_sha256": "474239bd8216a942e55c462b43a441a23abc8b96ed820ddb02de53c60b266beb", + "changes": [ + { + "before": " quarters.add(_qid(_attain(person.birth_date, 21)) + 1)\n", + "after": "" + } + ], + "spec_path": "scratch/review/round15-mutation-drop_age21_edge_year.json", + "log": "scratch/review/round15-mutation-drop_age21_edge_year.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round15 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round15 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND15_MUTATION=scratch/review/round15-mutation-drop_age21_edge_year.json .venv/bin/python scratch/review/run_round15_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_status_oracle.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.CURRENTLY-age", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.ALL-age" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "drop_period_years", + "source_sha256": "474239bd8216a942e55c462b43a441a23abc8b96ed820ddb02de53c60b266beb", + "changes": [ + { + "before": " quarters.update(range(_qid(period.start), _qid(period.end) + 1))\n", + "after": " pass\n" + } + ], + "spec_path": "scratch/review/round15-mutation-drop_period_years.json", + "log": "scratch/review/round15-mutation-drop_period_years.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round15 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round15 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND15_MUTATION=scratch/review/round15-mutation-drop_period_years.json .venv/bin/python scratch/review/run_round15_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_status_oracle.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.CURRENTLY-prior", + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.ALL-prior" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "drop_witness_order", + "source_sha256": "474239bd8216a942e55c462b43a441a23abc8b96ed820ddb02de53c60b266beb", + "changes": [ + { + "before": " key=lambda choice: not witness.issuperset(choice),\n", + "after": " key=lambda choice: False,\n" + } + ], + "spec_path": "scratch/review/round15-mutation-drop_witness_order.json", + "log": "scratch/review/round15-mutation-drop_witness_order.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round15 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round15 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND15_MUTATION=scratch/review/round15-mutation-drop_witness_order.json .venv/bin/python scratch/review/run_round15_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_status_oracle.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_15.py::test_a_moving_start_keeps_a_result_one_filling_attains" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "drop_reported_start_condition", + "source_sha256": "474239bd8216a942e55c462b43a441a23abc8b96ed820ddb02de53c60b266beb", + "changes": [ + { + "before": " if own_start == start and (\n", + "after": " if (\n" + } + ], + "spec_path": "scratch/review/round15-mutation-drop_reported_start_condition.json", + "log": "scratch/review/round15-mutation-drop_reported_start_condition.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round15 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round15 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND15_MUTATION=scratch/review/round15-mutation-drop_reported_start_condition.json .venv/bin/python scratch/review/run_round15_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_status_oracle.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_15.py::test_an_entitlement_window_cannot_borrow_the_starts_placement[InsuredTest.CURRENTLY-later" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "bound_stops_at_reported_start", + "source_sha256": "474239bd8216a942e55c462b43a441a23abc8b96ed820ddb02de53c60b266beb", + "changes": [ + { + "before": " horizon = _current_period_start_horizon(person, month)\n for quarter in range(_qid(start), _qid(horizon) + 1):\n try:\n completed, own_start = _complete_current_period(", + "after": " horizon = _current_period_start_horizon(person, month)\n for quarter in range(_qid(start), _qid(start) + 1):\n try:\n completed, own_start = _complete_current_period(" + } + ], + "spec_path": "scratch/review/round15-mutation-bound_stops_at_reported_start.json", + "log": "scratch/review/round15-mutation-bound_stops_at_reported_start.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round15 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round15 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND15_MUTATION=scratch/review/round15-mutation-bound_stops_at_reported_start.json .venv/bin/python scratch/review/run_round15_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_status_oracle.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_15.py::test_the_date_last_insured_alone_can_refuse_a_moving_start", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[102037]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[102202]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[103045]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[105793]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[109597]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[110777]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[203310]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[207027]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[207682]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[209481]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[209505]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[212010]", + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_matches_the_favorable_filling" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + } + ], + "round_15_runner_source": "\"\"\"Run named invented-data conformance tests with open-event auditing.\"\"\"\n\nimport hashlib\nimport json\nimport os\nfrom pathlib import Path\nimport sys\n\nCOUNTS = {\"restricted_opens\": 0, \"subprocess.Popen\": 0, \"os.system\": 0}\nBARRED = {\n \"gates.yaml\", \"adjusted_poverty.py\", \"rows.py\",\n \"ssa_trust_fund_interest_rates_2026.json\",\n \"urban2010_cola_comparison.md\", \"urban2010_fra68_comparison.md\",\n \"boomers2004_uniform_cut_comparison.md\", \"minimum_benefits_comparison.md\",\n \"m6_projection_engine.md\", \"mint8_table_user_guide.source.html\",\n \"test_anchor_provenance_erratum.py\",\n}\n\n\ndef audit(event, arguments):\n if event == \"open\" and isinstance(arguments[0], (str, bytes)):\n path = os.fsdecode(arguments[0])\n name = Path(path).name\n if (\n name in BARRED\n or name.startswith((\"adjusted_poverty.\", \"rows.\"))\n or \"/PolicyEngine/psid-data/\" in path\n or \"/microcosm-launch-evidence/\" in path\n or \"/dynasim-refs/\" in path\n or \"/claude-501/\" in path\n ):\n COUNTS[\"restricted_opens\"] += 1\n raise RuntimeError(path)\n elif event in (\"subprocess.Popen\", \"os.system\"):\n COUNTS[event] += 1\n\n\ndef main():\n for name in (\"POPULACE_DYNAMICS_PSID_DIR\", \"POPULACE_DYNAMICS_EPUF_DIR\"):\n assert os.environ[name] == \"/nonexistent/trackb-round15\"\n assert sys.argv[1:]\n assert all(\n not argument.startswith(\"tests/\") or \".py\" in argument\n for argument in sys.argv[1:]\n )\n sys.addaudithook(audit)\n from populace_dynamics.track_b import insured_status as insured\n\n source_path = Path(insured.__file__)\n original = source_path.read_bytes()\n baseline_path = os.environ.get(\"TRACKB_ROUND15_SOURCE\")\n if baseline_path:\n baseline = Path(baseline_path).read_bytes()\n exec(compile(baseline, str(source_path), \"exec\"), insured.__dict__)\n print(\"BASELINE\", hashlib.sha256(baseline).hexdigest(), flush=True)\n spec_path = os.environ.get(\"TRACKB_ROUND15_MUTATION\")\n if spec_path:\n spec = json.loads(Path(spec_path).read_text())\n assert hashlib.sha256(original).hexdigest() == spec[\"source_sha256\"]\n source = original.decode()\n for change in spec[\"changes\"]:\n assert source.count(change[\"before\"]) == 1, change[\"before\"]\n source = source.replace(change[\"before\"], change[\"after\"], 1)\n exec(compile(source, str(source_path), \"exec\"), insured.__dict__)\n print(\"MUTATION\", spec[\"name\"], flush=True)\n import pytest\n\n try:\n return pytest.main(sys.argv[1:])\n finally:\n assert source_path.read_bytes() == original\n print(\"OPEN_AUDIT\", json.dumps(COUNTS, sort_keys=True), flush=True)\n\n\nif __name__ == \"__main__\":\n raise SystemExit(main())\n", + "round_15_note": "All 21 mutations were killed by named public tests. On the first pass 14 were killed and seven survived, and a date-last-insured test killed one. The other six needed declarations the stress generator never drew. drop_disability_aggregate_refusal needed a blind record below six ordinary QCs, and the four first-start lines and the reported-start condition needed an entitlement month that ends a CURRENTLY window before the onset. Each run used nonexistent data roots, one thread per library, in-memory mutation only, unchanged implementation bytes, zero restricted opens and zero spawned-process audit events.", + "round_15_test_sha256": { + "tests/test_track_b_insured_status_fix_round_2.py": "7823aa52fdaed09b6df8f8c04629a5b9b7dbf3b367d2e4544c4f1acaa2c30dd7", + "tests/test_track_b_insured_status_fix_round_14.py": "2e4dad2953059addafd029ce4257fcb9bbc6b2c6cd529b5bed72be2ea1773525", + "tests/test_track_b_insured_status_fix_round_15.py": "fca4dec5ab4f4b027b793ada497c29ba056c098f3bee46d3bb109ab878431d45", + "tests/test_track_b_insured_status_status_stress.py": "811ce10bd1152b0c201735e4d7105e18c86d6c3f0415138e2bcd6c1227f354ff", + "tests/test_track_b_insured_status_status_oracle.py": "4b603ca88ea6b52e518dcc93ef08d67ed49f7604aa1894a3b50baedf47aa2b61" + }, + "round_15_replay": "Write round_15_runner_source to scratch/review/run_round15_named.py. For each round_15_mutations record, write name/source_sha256/changes to its spec_path, then execute its exact command. Mutations apply only in memory.", + "round_15_final_source_sha256": "474239bd8216a942e55c462b43a441a23abc8b96ed820ddb02de53c60b266beb" } diff --git a/src/populace_dynamics/track_b/insured_status.py b/src/populace_dynamics/track_b/insured_status.py index 42b520119..60c9d38c9 100644 --- a/src/populace_dynamics/track_b/insured_status.py +++ b/src/populace_dynamics/track_b/insured_status.py @@ -825,6 +825,109 @@ def _current_period_establishment_unknown(person): ) +def _pre1951_aggregate_possible( + person, years, credits, at, exit_month, required +): + """Bound Act 213(c)'s aggregate against one fully insured requirement. + + Post1950 upper credits are counted without period exclusions, and + unresolved history or establishment lowers the requirement to six. + This can only preserve a route; it never credits a deemed quarter. + """ + before1951 = {year: row for year, row in years.items() if year < 1951} + if not before1951: + return False + wages = sum( + ( + sum(row.quarterly_wages) + for row in before1951.values() + if row.quarterly_wages is not None + ), + Fraction(0), + ) + unknown_wages = any( + row.provenance is EarningsProvenance.UNKNOWN + for row in before1951.values() + ) + rows, _ = _world(person, credits, _qid(at), exit_month, False) + post1950 = sum( + len(_assign_qcs(*row)) for year, row in rows.items() if year >= 1951 + ) + if ( + person.prior_disability_periods_provenance + is EarningsProvenance.UNKNOWN + or person.disability_onset is not None + and person.disability_onset < _fra_date(person).replace(day=1) + and person.current_disability_period_provenance + is EarningsProvenance.UNKNOWN + ): + required = 6 + # Source conflict us:oasdi-insured-pre1951-seven-elapsed-years + return unknown_wages or ( + wages >= 400 and wages // 400 + post1950 >= required + ) + + +def _aggregate_could_insure( + person, years, credits, at, exit_month, *, onset=True +): + """Whether only the aggregate could be missing for insurance at ``at``. + + Act 223(c)(1)(A) and 216(i)(3)(A) require a "fully insured individual" + under section 214, the section Act 213(c) names, and 404.132 applies + 404.110 with only a different end to the elapsed years. RS 00301.315 + B.1 alone excludes disability claims. Filing facts stay unmodeled, so + a decisive aggregate refuses by name and is never rejected or answered + false. Simplified credits never count toward the recent rule. + """ + # Source conflict us:oasdi-insured-simplified-pre1951-disability-scope + if not ( + person.statutory_blindness + or _witness( + person, + credits, + at, + exit_month, + InsuredTest.DISABILITY, + onset=onset, + ignore_fully_insured=True, + )[0] + ): + return False + periods = tuple( + (period.start, period.end) + for period in person.prior_disability_periods + ) + return _pre1951_aggregate_possible( + person, + years, + credits, + at, + exit_month, + _requirement(person, at, periods, onset=onset, for_disability=True), + ) + + +def _aggregate_establishment_possible( + person, years, credits, horizon, exit_month +): + """Possibility bound: earliest requirement, credits through horizon.""" + periods = tuple( + (period.start, period.end) + for period in person.prior_disability_periods + ) + return _pre1951_aggregate_possible( + person, + years, + credits, + horizon, + exit_month, + _requirement( + person, person.disability_onset, periods, for_disability=True + ), + ) + + def _observable_coverage_paths( person, years, month, exit_month, kind, lo, quarter, upper, lower ): @@ -833,6 +936,8 @@ def _observable_coverage_paths( Act 213(c), 404.110(d), and RS 00301.315 make the pre1951 aggregate method available independently of an optional specialist flag. Its application, retroactivity and section227 conditions are not declared. + DISABILITY compares the recent rule at each event with the same + bound; a true ordinary status stays computed. RS .315 B.1.a describes the 1967 seven-EY condition; B.1.b removes it under the 1990 amendments. 404.110(d)(1)(ii) supplies a June1992 application exception with section227 conditions. A potentially @@ -851,27 +956,6 @@ def _observable_coverage_paths( ): return if kind is InsuredTest.FULLY: - before1951 = {year: row for year, row in years.items() if year < 1951} - if not before1951: - return - wages = sum( - ( - sum(row.quarterly_wages) - for row in before1951.values() - if row.quarterly_wages is not None - ), - Fraction(0), - ) - unknown_wages = any( - row.provenance is EarningsProvenance.UNKNOWN - for row in before1951.values() - ) - rows, _ = _world(person, upper, _qid(month), exit_month, False) - post1950 = sum( - len(_assign_qcs(*row)) - for year, row in rows.items() - if year >= 1951 - ) periods = tuple( (period.start, period.end) for period in person.prior_disability_periods @@ -880,33 +964,37 @@ def _observable_coverage_paths( # lower prerequisite would favor the simplified aggregate instead. # Use every known period, including a derived current period, and # the universal six-QC lower bound for unresolved applicability. - required = min(lo[6], _requirement(person, month, periods)) - if ( - person.prior_disability_periods_provenance - is EarningsProvenance.UNKNOWN - or person.disability_onset is not None - and person.disability_onset < _fra_date(person).replace(day=1) - and person.current_disability_period_provenance - is EarningsProvenance.UNKNOWN - ): - required = 6 - # Source conflict us:oasdi-insured-pre1951-seven-elapsed-years - if unknown_wages or ( - wages >= 400 and wages // 400 + post1950 >= required + if _pre1951_aggregate_possible( + person, + years, + upper, + month, + exit_month, + min(lo[6], _requirement(person, month, periods)), ): _refuse( InsuredUnsupportedReason.SIMPLIFIED_PRE1951, "Pre1951 wages may establish fully insured status under " "Act213(c); filing and retroactivity facts are unmodeled", ) - elif kind is InsuredTest.DISABILITY and _pre1956_alternate_possible( - person, upper, month, exit_month, lower_credits=lower - ): - _refuse( - InsuredUnsupportedReason.DISABILITY_BEFORE_1956, - "Onset and QCs allow the RS00301.480 alternate test; " - "application conditions are unmodeled", - ) + elif kind is InsuredTest.DISABILITY: + if _pre1956_alternate_possible( + person, upper, month, exit_month, lower_credits=lower + ): + _refuse( + InsuredUnsupportedReason.DISABILITY_BEFORE_1956, + "Onset and QCs allow the RS00301.480 alternate test; " + "application conditions are unmodeled", + ) + if not lo[0] and any( + _aggregate_could_insure(person, years, upper, event, exit_month) + for event in _events(person, month, kind) + ): + _refuse( + InsuredUnsupportedReason.SIMPLIFIED_PRE1951, + "Pre1951 wages may supply the disability fully insured " + "prerequisite; filing facts are unmodeled", + ) def _pre1956_alternate_possible( @@ -1378,7 +1466,7 @@ def _fra_quarter(person): return _qid(_fra_date(person)) -def _last_insured(person, credits, month, exit_month): +def _last_insured(person, credits, month, exit_month, *, years=None): last = None if sum(len(fixed) + flexible for fixed, flexible in credits.values()) < 6: return None, False @@ -1410,6 +1498,14 @@ def _last_insured(person, credits, month, exit_month): )[0]: last = _qend(qid) break + if years is not None and _aggregate_could_insure( + person, years, credits, at, exit_month, onset=False + ): + _refuse( + InsuredUnsupportedReason.SIMPLIFIED_PRE1951, + "Pre1951 wages may extend the date last insured; " + "filing facts are unmodeled", + ) censored = ( (exit_month is None or exit_month > month) and cap == _qid(month) @@ -1521,6 +1617,11 @@ def _with_current_period( "First insured start depends on annual placement " "or prior treatment", ) + return _complete_current_period(person, quarter) + + +def _complete_current_period(person, quarter): + fra = _fra_date(person) # 416(i)(2)(C), 404.321(a): onset day if insured then, otherwise # first day of the first later insured quarter. Application/duration # are administrative facts declared by the caller, never inferred. @@ -1559,6 +1660,195 @@ def _with_current_period( return completed, start +def _start_fixed(person, credits, start, month, exit_month): + """Whether every annual placement insures the favorable first start. + + Without prior periods every window is a suffix ending at the tested + quarter. Placing annual QCs as early as possible before that quarter's + year and as late as possible in it is therefore the worst filling. If + even that filling is insured, no filling starts later, and the + favorable start already precedes none. Prior periods retain credited + endpoints, so no single worst filling exists and the caller enumerates. + """ + if person.prior_disability_periods: + return False + rows, _ = _world(person, credits, _qid(month), exit_month, False) + worst = dict(credits) + for year, (fixed, count, allowed) in rows.items(): + if count: + vacant = sorted(q for q in allowed if q not in fixed) + chosen = vacant[-count:] if year == start.year else vacant[:count] + worst[year] = (tuple(sorted((*fixed, *chosen))), 0) + return _witness(person, worst, start, exit_month, InsuredTest.DISABILITY)[ + 0 + ] + + +def _start_sensitive_years(person, horizon): + """Years whose annual placement can change a first insured quarter. + + A year wholly inside every tested window, and untouched by a period, + adds its full count wherever its QCs fall. Only the window's back + edges, the onset-to-horizon years and prior-period years can differ. + The 12-quarter and age-21 edges belong to 404.130(c) and (d). Recent-rule + windows want a back-edge QC late, but an entitlement month can end a + CURRENTLY window in that year and want it early, so placement stays + enumerated there. + """ + onset = _qid(person.disability_onset) + last = _qid(horizon) + excluded = sum( + _qid(period.end) - _qid(period.start) + 1 + for period in person.prior_disability_periods + ) + quarters = set(range(onset - 39 - excluded, last - 38)) + quarters.update(range(onset, last + 1)) + quarters.update(range(onset - 11 - excluded, last - 10)) + quarters.add(_qid(_attain(person.birth_date, 21)) + 1) + for period in person.prior_disability_periods: + quarters.update(range(_qid(period.start), _qid(period.end) + 1)) + return {quarter // 4 for quarter in quarters} + + +def _period_outcomes( + person, completed, start, credits, month, exit_month, kinds, dated +): + """Statuses and date last insured for each ending of one start.""" + for option in _current_period_completions(person, completed, start, month): + statuses = tuple( + _decision_witness(option, credits, month, exit_month, kind)[0][0] + for kind in kinds + ) + last = ( + _last_insured(option, credits, month, exit_month)[0] + if dated + else None + ) + yield statuses, last + + +def _improves(outcome, returned, last_insured): + statuses, last = outcome + return any( + found and not kept + for found, kept in zip(statuses, returned, strict=True) + ) or (last or date.min) > (last_insured or date.min) + + +def _settle_first_start( + person, + credits, + start, + month, + exit_month, + kinds, + returned, + *, + dated, + last_insured, +): + """Refuse a result no filling and its own first start can support. + + Each status above places annual QCs favorably for its own window, and + the established start does the same (RS00301.230). The two can rest on + different placements. 404.321(a) gives one record one start, and the + period's exclusions then shape FULLY, CURRENTLY and the date last + insured. When placement or prior treatment can move the start, the + result stands only if one filling attains it with the reported start + as its own and no filling can improve on it. Flexible credits bound + every filling at each possible start, so a bound that allows an + improvement refuses by name. Otherwise the search begins at the filling + that insures the start, varies the latest years first, and stops at the + first filling that attains the result. A year that cannot move the + start stays flexible, so each status still places it favorably. + """ + # Source conflict us:oasdi-insured-one-filling-first-start + if _start_fixed(person, credits, start, month, exit_month): + return + horizon = _current_period_start_horizon(person, month) + for quarter in range(_qid(start), _qid(horizon) + 1): + try: + completed, own_start = _complete_current_period( + person, _qdate(quarter) + ) + except InvalidFamilyInput: + continue + if any( + _improves(outcome, returned, last_insured) + for outcome in _period_outcomes( + person, + completed, + own_start, + credits, + month, + exit_month, + kinds, + dated, + ) + ): + _refuse( + InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, + "First insured start depends on annual placement " + "or prior treatment", + ) + witness = set( + _witness(person, credits, start, exit_month, InsuredTest.DISABILITY)[4] + ) + rows, _ = _world(person, credits, _qid(month), exit_month, False) + sensitive = _start_sensitive_years(person, horizon) + options = { + year: sorted( + _assignment_candidates(*row), + key=lambda choice: not witness.issuperset(choice), + ) + for year, row in rows.items() + if year in sensitive and row[1] + } + for index, choices in enumerate(product(*options.values())): + if index == 4096: + _refuse( + InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, + "More than 4096 first-start annual placements", + ) + filling = dict(credits) + filling.update( + (year, (choice, 0)) + for year, choice in zip(options, choices, strict=True) + ) + for treatment in ( + (True, False) if person.prior_disability_periods else (None,) + ): + try: + completed, own_start = _with_current_period( + person, + filling, + month, + exit_month, + use_periods_only=treatment, + ) + except InvalidFamilyInput: + continue + if own_start == start and ( + returned, + last_insured, + ) in _period_outcomes( + person, + completed, + own_start, + filling, + month, + exit_month, + kinds, + dated, + ): + return + _refuse( + InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, + "First insured start depends on annual placement " + "or prior treatment", + ) + + def _current_period_completions(person, completed, start, month): """Every possible end quarter through query, plus continuation. @@ -1762,6 +2052,7 @@ def _recent_rule_possible( InsuredTest.DISABILITY, use_periods_only=treatment, )[0] + # Source conflict us:oasdi-insured-flag-first-insured-quarter rule_met = ( person.statutory_blindness or ordinary @@ -1801,6 +2092,7 @@ def _unknown_prior_joint_shortfall(person, rows, horizon, fully_route): This is only a necessary-condition proof, never a concrete witness. The historical alternate is handled separately by the caller. """ + # Source conflict us:oasdi-insured-unknown-prior-historical-blindness options = [_assignment_candidates(*row) for row in rows.values()] if prod(map(len, options)) > 4096: return False @@ -1906,6 +2198,8 @@ def _could_establish_current_period( insurance for one filling and treatment fixes an overlapping first start, including with blindness (404.321(a)). A construction refusal preserves possibility until later validation has checked input errors. + A decisive pre1951 aggregate is an automatic fully route, with or + without its flag; it never counts toward the recent rule. """ if not person.current_disability_period_established: return True @@ -1931,7 +2225,11 @@ def _could_establish_current_period( and maximum_qcs < _minimum_current_period_qcs(person) ): return False - fully_route = bool(person.conditions & _FULLY_INSURED_ROUTE_CONDITIONS) + fully_route = bool( + person.conditions & _FULLY_INSURED_ROUTE_CONDITIONS + ) or _aggregate_establishment_possible( + person, years, credits, horizon, exit_month + ) if fully_route and person.statutory_blindness: return _recent_rule_possible( person, credits, horizon, exit_month, lower_credits=lower_credits @@ -2129,7 +2427,10 @@ def insured_status( history changes windows or special eligibility, never this floor. With known nonblind history, fully-route flags must retain a recent first insured start outside prior quarters, or automatic pre1956 - alternate. UNKNOWN history also faces a joint optimistic-clock proof + alternate. A pre1951 aggregate that could supply a failed fully insured + prerequisite is such a route without a flag, and DISABILITY, the + start and the date last insured refuse by name when it decides them. + UNKNOWN history also faces a joint optimistic-clock proof permitting past blindness; survival never claims a concrete history. A fully-route flag's start is unknown, including with blindness; only ordinary insurance for the same filling and treatment fixes an @@ -2138,7 +2439,9 @@ def insured_status( its prior-period clock and credited endpoints remain unchanged. If a clear first start depends on annual placement or prior treatment after a favorable overlapping start, retain a named boundary refusal. - A first successful filling cannot settle the other requested statuses. + A first successful filling cannot settle the other requested statuses: + wherever placement or treatment can move the start, one filling with + its own start must attain the returned result and none may beat it. The pre1956 flag adds no route beyond the automatic alternate. A flag's own conditions remain declared facts and are not tested. History validation runs first. Uncomputable QC rows use bounded @@ -2262,9 +2565,36 @@ def insured_status( InsuredUnsupportedReason.UNKNOWN_EARNINGS, "Unknown earnings decide a valid established current period", ) + # Only an automatic aggregate route can reach this point with + # known credits and no ordinary start. + if _aggregate_establishment_possible( + person, + years, + upper, + _current_period_start_horizon(person, month), + coverage_end_month, + ): + _refuse( + InsuredUnsupportedReason.SIMPLIFIED_PRE1951, + "Pre1951 wages may supply the current period's fully " + "insured prerequisite; filing facts are unmodeled", + ) # With known credits the shared possibility predicate already # validated this identical construction before any refusal. raise + # An aggregate could insure an earlier quarter than the ordinary + # first start, and 404.321(a) then moves the period's start. + if lo_start is not None and any( + _aggregate_could_insure( + person, years, upper, _qdate(quarter), coverage_end_month + ) + for quarter in range(_qid(person.disability_onset), _qid(lo_start)) + ): + _refuse( + InsuredUnsupportedReason.SIMPLIFIED_PRE1951, + "Pre1951 wages may move the first insured start; " + "filing facts are unmodeled", + ) if lo_start != hi_start: _refuse( InsuredUnsupportedReason.UNKNOWN_EARNINGS, @@ -2436,12 +2766,12 @@ def insured_status( dli = None if test in (InsuredTest.ALL, InsuredTest.DISABILITY): lower_dates = [ - _last_insured(p, lower, month, coverage_end_month) + _last_insured(p, lower, month, coverage_end_month, years=years) for p in lo_completions ] upper_dates = ( [ - _last_insured(p, upper, month, coverage_end_month) + _last_insured(p, upper, month, coverage_end_month, years=years) for p in hi_completions ] if unknown @@ -2462,6 +2792,25 @@ def insured_status( # false current status cannot prove a positive DLI lower date. lo_date = None dli = _computed(DLIRange, lo_date, hi_date, lo_censored or hi_censored) + if lo_start is not None: + kinds = tuple( + kind + for kind in (InsuredTest.FULLY, InsuredTest.CURRENTLY) + if decisions[kind] is not None + ) + _settle_first_start( + person, + upper, + hi_start, + month, + coverage_end_month, + kinds, + tuple(decisions[kind].insured for kind in kinds), + dated=dli is not None and not prior_unknown, + last_insured=( + dli.upper if dli is not None and not prior_unknown else None + ), + ) lo_rows, _ = _world( lo_person, lower, diff --git a/tests/README-tiers.md b/tests/README-tiers.md index c8f859972..fad9d48ad 100644 --- a/tests/README-tiers.md +++ b/tests/README-tiers.md @@ -39,9 +39,9 @@ pytest --collect-only -q -m oracle_policyengine | tail -1 | Tier | Tests at HEAD | |---|---:| -| `unit` | 21,273 | +| `unit` | 21,336 | | `artifact` | 4,271 | | `integration_psid` | 1,471 | | `reproduction_legacy` | 520 | | `oracle_policyengine` | 308 | -| **Total** | **27,843** | +| **Total** | **27,906** | diff --git a/tests/test_track_b_insured_status_fix_round_14.py b/tests/test_track_b_insured_status_fix_round_14.py index fbd5ab79a..91b8bcae2 100644 --- a/tests/test_track_b_insured_status_fix_round_14.py +++ b/tests/test_track_b_insured_status_fix_round_14.py @@ -726,7 +726,7 @@ def test_six_qc_special_prior_attack_keeps_unknown_row(): def _simplified_prior_basis(flag=None): - """A deliberately inadmissible aggregate disability-prior basis.""" + """A disability prior that only the aggregate could fund.""" person = _person( birth=date(1926, 2, 2), disability_onset=date(1989, 1, 15), @@ -753,10 +753,16 @@ def _simplified_prior_basis(flag=None): return person, years, month -def test_unchanged_simplified_prior_basis_does_not_insure_disability(): - """RS 00301.315 B.1 excludes this ordinary-to-aggregate conversion.""" +def test_simplified_prior_basis_keeps_a_named_refusal(): + """Acts 213(c), 223(c)(1)(A) reach this prior; RS .315 B.1 does not.""" person, years, month = _simplified_prior_basis() - _invalid(person, years, month, test=i.InsuredTest.DISABILITY) + _refusal( + person, + years, + month, + i.InsuredUnsupportedReason.UNKNOWN_PERIODS, + test=i.InsuredTest.DISABILITY, + ) def test_unchanged_declared_simplified_prior_basis_keeps_named_refusal(): diff --git a/tests/test_track_b_insured_status_fix_round_15.py b/tests/test_track_b_insured_status_fix_round_15.py new file mode 100644 index 000000000..71540016d --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_15.py @@ -0,0 +1,639 @@ +"""Round 15: the disability aggregate and each filling's own start. + +Verification class: statutory conformance on invented declarations; no +population, behavioral or forecast claim. A decisive pre-1951 aggregate +(Act 213(c); 404.132) refuses by name on DISABILITY, the established period, +its first start and the date last insured. It never loses a row, and +simplified credits never count toward the recent rule. Source conflict +us:oasdi-insured-simplified-pre1951-disability-scope. + +One record has one start (404.321(a)). A result stands only if one filling +attains it with the reported start as its own, and no filling can improve on +it. Source conflict us:oasdi-insured-one-filling-first-start. +""" + +from dataclasses import replace +from datetime import date +from fractions import Fraction + +import pytest +from hypothesis import example, given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as i +from populace_dynamics.track_b.gross_benefits import ( + InvalidFamilyInput, + count_family_outcomes, +) +from tests.test_track_b_insured_status import history + +OBSERVED = i.EarningsProvenance.OBSERVED +UNKNOWN = i.EarningsProvenance.UNKNOWN +SIMPLIFIED = i.InsuredUnsupportedReason.SIMPLIFIED_PRE1951 +ASSIGNMENT = i.InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY +WEIGHT = Fraction(13, 7) +BIRTH = date(1926, 2, 2) +ONSET = date(1989, 1, 15) +QUERY = date(1990, 1, 1) +# Three ordinary QCs, or eighteen simplified ones, plus 22 recent QCs: +# 25 ordinary and 40 simplified against the 37 required at onset. +RECENT = {1983: 2, **dict.fromkeys(range(1984, 1989), 4)} +PROPERTY = settings(max_examples=24, deadline=None) + + +def _person(**changes): + values = dict( + sex=i.Sex.FEMALE, + disability_onset=ONSET, + current_disability_period_established=True, + current_disability_period_provenance=OBSERVED, + current_disability_period_end=date(1989, 12, 31), + current_disability_period_end_provenance=OBSERVED, + prior_disability_periods=(), + prior_disability_periods_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + birth = changes.pop("birth", BIRTH) + values.update(changes) + return i.Person(birth, **values) + + +def _unestablished(**changes): + values = dict( + sex=i.Sex.FEMALE, + current_disability_period_established=False, + current_disability_period_provenance=OBSERVED, + prior_disability_periods=(), + prior_disability_periods_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + values.update(changes) + return i.Person(BIRTH, **values) + + +def _medical(): + return _unestablished(disability_onset=ONSET) + + +def _no_onset(): + return _unestablished() + + +def _wages(amount): + return i.CoverageYear( + OBSERVED, + quarterly_wages=( + Fraction(amount), + Fraction(0), + Fraction(0), + Fraction(0), + ), + ) + + +def _years(person, month, amount=2400, counts=None): + years = history(person, month, RECENT if counts is None else counts) + for year in (1948, 1949, 1950): + years[year] = _wages(amount) + return years + + +def _row(person, years, month, *, test=i.InsuredTest.ALL): + row = i.evaluate_insured_status( + "round-fifteen-aggregate", + WEIGHT, + lambda: i.insured_status(person, years, month, test=test), + ) + counts = count_family_outcomes((row,)) + assert counts.rows == 1 + assert counts.weight == WEIGHT + assert counts.unsupported_weight == (WEIGHT if row.unsupported else 0) + return row + + +def _reason(person, years, month, *, test=i.InsuredTest.ALL): + row = _row(person, years, month, test=test) + assert row.result is None + return row.unsupported.reason + + +def _computed(person, years, month, *, test=i.InsuredTest.ALL): + row = _row(person, years, month, test=test) + assert not row.unsupported + return row.result + + +@pytest.mark.parametrize( + "test", + (i.InsuredTest.FULLY, i.InsuredTest.DISABILITY, i.InsuredTest.ALL), +) +def test_aggregate_keeps_the_established_period_row(test): + person = _person() + years = _years(person, QUERY) + assert _reason(person, years, QUERY, test=test) is SIMPLIFIED + + +@pytest.mark.parametrize("test", (i.InsuredTest.DISABILITY, i.InsuredTest.ALL)) +def test_aggregate_refuses_a_false_disability_after_medical_onset(test): + person = _medical() + years = _years(person, QUERY) + assert _reason(person, years, QUERY, test=test) is SIMPLIFIED + + +def test_aggregate_refuses_a_false_disability_without_onset(): + month = date(1989, 1, 1) + person = _no_onset() + years = _years(person, month) + assert ( + _reason(person, years, month, test=i.InsuredTest.DISABILITY) + is SIMPLIFIED + ) + + +def test_aggregate_refuses_for_blindness_without_the_recent_rule(): + person = _medical() + person = replace(person, statutory_blindness=True) + years = _years(person, QUERY, counts=dict.fromkeys(range(1980, 1985), 4)) + assert ( + _reason(person, years, QUERY, test=i.InsuredTest.DISABILITY) + is SIMPLIFIED + ) + + +def test_blind_established_period_keeps_the_aggregate_row(): + person = replace(_person(), statutory_blindness=True) + years = _years(person, QUERY, counts=dict.fromkeys(range(1980, 1985), 4)) + assert _reason(person, years, QUERY) is SIMPLIFIED + + +@pytest.mark.parametrize("test", (i.InsuredTest.DISABILITY, i.InsuredTest.ALL)) +def test_declared_flag_and_automatic_route_share_their_reason(test): + person = _person( + conditions=(i.CoverageCondition.SIMPLIFIED_PRE1951,), + ) + years = _years(person, QUERY) + assert _reason(person, years, QUERY, test=test) is SIMPLIFIED + + +@pytest.mark.parametrize("amount,refuses", ((2000, True), (1999, False))) +def test_disability_boundary_is_one_whole_400_credit(amount, refuses): + """$6,000 gives 15 + 22 = 37; $5,997 gives 14 + 22 = 36.""" + person = _medical() + years = _years(person, QUERY, amount) + if refuses: + assert ( + _reason(person, years, QUERY, test=i.InsuredTest.DISABILITY) + is SIMPLIFIED + ) + else: + result = _computed(person, years, QUERY, test=i.InsuredTest.DISABILITY) + assert not result.disability.insured + + +@PROPERTY +@example(cents=600000) +@example(cents=599999) +@given(st.integers(min_value=0, max_value=900000)) +def test_disability_refusal_tracks_the_exact_aggregate(cents): + person = _medical() + years = _years(person, QUERY, Fraction(cents, 300)) + row = _row(person, years, QUERY, test=i.InsuredTest.DISABILITY) + if cents >= 600000: + assert row.unsupported.reason is SIMPLIFIED + else: + assert not row.result.disability.insured + + +def test_simplified_credits_never_count_toward_the_recent_rule(): + counts = dict.fromkeys(range(1968, 1975), 4) + person = _medical() + years = _years(person, QUERY, counts=counts) + result = _computed(person, years, QUERY, test=i.InsuredTest.DISABILITY) + assert not result.disability.insured + person = _person() + with pytest.raises(InvalidFamilyInput): + i.insured_status(person, _years(person, QUERY, counts=counts), QUERY) + + +def test_ordinary_insurance_stays_computed_with_the_aggregate(): + counts = {**RECENT, **dict.fromkeys(range(1978, 1983), 4)} + person = _medical() + with_wages = _years(person, QUERY, counts=counts) + result = _computed( + person, with_wages, QUERY, test=i.InsuredTest.DISABILITY + ) + assert result.disability.insured + + +def test_no_pre1951_wages_keeps_the_ordinary_answers(): + person = _medical() + years = history(person, QUERY, RECENT) + result = _computed(person, years, QUERY, test=i.InsuredTest.DISABILITY) + assert not result.disability.insured + established = _person() + with pytest.raises(InvalidFamilyInput): + i.insured_status( + established, + history(established, QUERY, RECENT), + QUERY, + ) + + +def _first_start_record(amount): + person = _person(current_disability_period_end=date(1990, 12, 31)) + month = date(1991, 1, 1) + counts = { + **dict.fromkeys(range(1981, 1989), 4), + 1980: 1, + 1990: 1, + } + return person, _years(person, month, amount, counts), month + + +def test_aggregate_can_move_the_first_insured_start(): + """37 ordinary QCs first appear in 1990; 18 + 34 insure the onset.""" + person, years, month = _first_start_record(2400) + assert _reason(person, years, month) is SIMPLIFIED + + +def test_first_start_control_without_a_400_dollar_aggregate(): + person, years, month = _first_start_record(50) + result = _computed(person, years, month) + assert result.disability.insured + assert result.disability.qualifying_quarter == date(1990, 1, 1) + + +def _last_insured_record(amount): + """Ordinary fully status lapses in 1979, the recent rule in 1983.""" + month = date(1985, 1, 1) + person = _no_onset() + counts = dict.fromkeys(range(1972, 1978), 4) + return person, _years(person, month, amount, counts), month + + +def test_aggregate_can_extend_the_date_last_insured(): + person, years, month = _last_insured_record(2400) + assert ( + _reason(person, years, month, test=i.InsuredTest.DISABILITY) + is SIMPLIFIED + ) + + +def test_date_last_insured_control_without_a_400_dollar_aggregate(): + person, years, month = _last_insured_record(50) + result = _computed(person, years, month, test=i.InsuredTest.DISABILITY) + assert not result.disability.insured + assert result.dli.lower == date(1978, 12, 31) + + +def _unknown_prior_record(amount): + """A prior funded by the aggregate could reopen the 40-quarter window.""" + person = _person( + prior_disability_periods=(), + prior_disability_periods_provenance=UNKNOWN, + ) + years = history( + person, + QUERY, + {1964: 4, 1965: 4, 1966: 4, 1967: 2, 1987: 4, 1988: 2}, + ) + years[1950] = _wages(amount) + return person, years + + +def test_unknown_prior_history_keeps_the_aggregate_row(): + person, years = _unknown_prior_record(1200) + assert ( + _reason(person, years, QUERY, test=i.InsuredTest.DISABILITY) + is i.InsuredUnsupportedReason.UNKNOWN_PERIODS + ) + + +def test_unknown_prior_control_needs_a_400_dollar_aggregate(): + person, years = _unknown_prior_record(50) + with pytest.raises(InvalidFamilyInput): + i.insured_status(person, years, QUERY, test=i.InsuredTest.DISABILITY) + + +def test_mapping_order_leaves_the_disability_reason_unchanged(): + person = _medical() + years = _years(person, QUERY) + forward = _reason(person, years, QUERY, test=i.InsuredTest.DISABILITY) + reverse = _reason( + person, + dict(reversed(tuple(years.items()))), + QUERY, + test=i.InsuredTest.DISABILITY, + ) + assert forward is reverse is SIMPLIFIED + + +def _outcome(person, years, month, test): + try: + result = i.insured_status(person, years, month, test=test) + except i.InsuredConfigurationUnsupported as error: + return "refused", error.reason + except InvalidFamilyInput: + return "invalid", None + return "computed", result + + +@PROPERTY +@given( + amount=st.sampled_from((0, 50, 399, 400, 2000, 2400, 5000)), + start=st.integers(1978, 1985), + span=st.integers(1, 11), + filled=st.integers(0, 4), + established=st.booleans(), + blind=st.booleans(), +) +def test_pre1951_wages_only_add_rows( + amount, start, span, filled, established, blind +): + """Adding raw pre-1951 wages never turns a row into an input error.""" + counts = { + year: filled + for year in range(max(start, 1978), min(start + span, 1989)) + if filled + } + person = replace( + _person() if established else _medical(), + statutory_blindness=blind, + ) + base = history(person, QUERY, counts) + added = _years(person, QUERY, amount, counts) + before = _outcome(person, base, QUERY, i.InsuredTest.ALL) + after = _outcome(person, added, QUERY, i.InsuredTest.ALL) + if before[0] != "invalid": + assert after[0] != "invalid", (before, after) + + +@PROPERTY +@given( + amount=st.sampled_from((400, 800, 2000, 2400, 5000)), + start=st.integers(1978, 1985), + span=st.integers(2, 11), +) +def test_fully_refusal_and_a_met_recent_rule_never_compute_false( + amount, start, span +): + """The same facts cannot refuse FULLY and answer DISABILITY false.""" + counts = {year: 4 for year in range(start, min(start + span, 1989))} + person = _medical() + years = _years(person, QUERY, amount, counts) + fully = _outcome(person, years, QUERY, i.InsuredTest.FULLY) + disability = _outcome(person, years, QUERY, i.InsuredTest.DISABILITY) + recent = sum(count for year, count in counts.items() if year >= 1979) >= 20 + if fully[:2] == ("refused", SIMPLIFIED) and recent: + if disability[0] == "computed": + assert disability[1].disability.insured + + +def _moving_start_person(**changes): + values = dict( + birth=date(1956, 2, 2), + disability_onset=date(1992, 1, 15), + current_disability_period_end=date(1994, 9, 30), + ) + values.update(changes) + return _person(**values) + + +# The 1994 QC must sit in the first insured quarter, so at most two later +# quarters leave the 13-quarter window and five of six QCs remain in every +# lawful filling. +MOVING_START = { + 1987: 2, + 1988: 4, + 1989: 3, + 1990: 4, + 1991: 4, + 1992: 2, + 1994: 1, +} +MOVING_QUERY = date(1995, 1, 1) + + +@pytest.mark.parametrize("test", (i.InsuredTest.CURRENTLY, i.InsuredTest.ALL)) +def test_no_filling_carries_the_start_and_the_status_together(test): + person = _moving_start_person() + years = history(person, MOVING_QUERY, MOVING_START) + assert _reason(person, years, MOVING_QUERY, test=test) is ASSIGNMENT + + +def test_a_partial_year_that_cannot_move_the_start_stays_computed(): + person = _moving_start_person() + counts = {**dict.fromkeys(range(1982, 1992), 4), 1992: 2} + result = _computed( + person, history(person, MOVING_QUERY, counts), MOVING_QUERY + ) + assert result.current_disability_period_start == date(1992, 1, 15) + assert result.disability.insured + + +def test_a_moving_start_keeps_a_result_one_filling_attains(): + """The search starts at the filling that insures the reported start.""" + person = _person( + birth=date(1978, 2, 2), + disability_onset=date(2011, 1, 15), + current_disability_period_end=date(2013, 12, 31), + ) + month = date(2014, 1, 1) + counts = { + 2002: 2, + 2003: 2, + 2004: 4, + 2006: 1, + 2007: 2, + 2008: 2, + 2009: 3, + 2010: 1, + 2011: 1, + 2012: 2, + } + result = _computed( + person, + history(person, month, counts), + month, + test=i.InsuredTest.DISABILITY, + ) + assert result.current_disability_period_start == date(2012, 4, 1) + + +@pytest.mark.parametrize( + ("amount", "refused"), + ((Fraction(2950), True), (Fraction(2900), False)), +) +def test_blind_aggregate_decides_below_six_ordinary_qcs(amount, refused): + """The date-last-insured scan stops below six, so this site decides. + + Three first-quarter wages earn three ordinary QCs, under the $3,000 + that would earn gift QCs. Elapsed years run 1951 through 1972, so 22 + QCs insure: $8,850 reaches 22 at $400 each, and $8,700 reaches 21. + """ + person = replace( + _unestablished( + disability_onset=date(1973, 2, 15), statutory_blindness=True + ), + birth_date=date(1926, 2, 2), + ) + month = date(1974, 7, 1) + years = _years(person, month, amount, {}) + if refused: + assert _reason( + person, years, month, test=i.InsuredTest.DISABILITY + ) is (SIMPLIFIED) + else: + row = _row(person, years, month, test=i.InsuredTest.DISABILITY) + assert row.result.disability.insured is False + + +def test_the_date_last_insured_alone_can_refuse_a_moving_start(): + """DISABILITY never reads the period, so only the date can differ.""" + person = _person( + birth=date(1973, 2, 2), + disability_onset=date(2015, 5, 15), + current_disability_period_end=date(2018, 1, 31), + prior_disability_periods=( + i.DisabilityPeriod(date(2013, 1, 1), date(2014, 12, 31)), + ), + ) + month = date(2022, 1, 1) + counts = { + 2008: 2, + 2009: 2, + 2010: 4, + 2011: 4, + 2012: 4, + 2013: 1, + 2014: 4, + 2015: 3, + 2016: 4, + } + years = history(person, month, counts) + assert _reason(person, years, month, test=i.InsuredTest.DISABILITY) is ( + ASSIGNMENT + ) + + +# An entitlement month ends a currently insured window in a year before the +# onset. That year then wants its QC early for the status and late for the +# recent rule, so each row needs the first-start search to vary that year. +# Each row names the only line of _start_sensitive_years that reaches it, +# and "later start" keeps the status only on a filling whose start differs. +# All QC arithmetic sits on the row: the fixed QCs leave one short of the +# recent rule, and the event's 13 quarters leave one short of six. +ENTITLEMENT_CONFLICTS = { + "forty quarter back edge": dict( + birth=date(1960, 2, 2), + disability_onset=date(2010, 1, 15), + current_disability_period_end=date(2013, 12, 31), + dib_entitlement_month=date(2000, 1, 1), + month=date(2015, 1, 1), + counts={ + 1990: 4, + 1991: 4, + 1998: 3, + 1999: 2, + 2000: 1, + **dict.fromkeys(range(2001, 2005), 4), + 2005: 3, + }, + ), + "later start": dict( + birth=date(1960, 2, 2), + disability_onset=date(2010, 8, 15), + current_disability_period_end=date(2013, 12, 31), + dib_entitlement_month=date(2000, 1, 1), + month=date(2015, 1, 1), + counts={ + 1990: 4, + 1991: 4, + 1998: 3, + 1999: 2, + 2000: 1, + **dict.fromkeys(range(2002, 2006), 4), + 2006: 3, + 2011: 1, + }, + ), + "prior period year": dict( + birth=date(1960, 2, 2), + disability_onset=date(2010, 8, 15), + current_disability_period_end=date(2011, 6, 30), + dib_entitlement_month=date(2005, 1, 1), + prior_disability_periods=( + i.DisabilityPeriod(date(2005, 1, 1), date(2005, 9, 30)), + ), + month=date(2012, 1, 1), + counts={ + 1990: 4, + 1991: 4, + 2000: 4, + 2002: 3, + 2003: 2, + 2005: 1, + 2006: 4, + 2007: 4, + 2008: 2, + }, + ), + "twelve quarter back edge": dict( + birth=date(1985, 2, 2), + disability_onset=date(2008, 8, 15), + current_disability_period_end=date(2009, 6, 30), + dib_entitlement_month=date(2005, 1, 1), + month=date(2010, 1, 1), + counts={ + 2002: 2, + 2003: 2, + 2004: 1, + 2005: 1, + 2006: 2, + 2007: 2, + 2008: 1, + }, + ), + "age 21 back edge": dict( + birth=date(1980, 8, 2), + disability_onset=date(2008, 8, 15), + current_disability_period_end=date(2009, 6, 30), + dib_entitlement_month=date(2001, 1, 1), + month=date(2010, 1, 1), + counts={ + 1999: 3, + 2000: 2, + 2001: 1, + **dict.fromkeys(range(2002, 2008), 2), + 2008: 1, + }, + ), +} + + +@pytest.mark.parametrize("name", ENTITLEMENT_CONFLICTS) +@pytest.mark.parametrize("test", (i.InsuredTest.CURRENTLY, i.InsuredTest.ALL)) +def test_an_entitlement_window_cannot_borrow_the_starts_placement(name, test): + values = dict(ENTITLEMENT_CONFLICTS[name]) + month, counts = values.pop("month"), values.pop("counts") + person = _person(**values) + years = history(person, month, counts) + assert _reason(person, years, month, test=test) is ASSIGNMENT + + +@pytest.mark.parametrize("name", ENTITLEMENT_CONFLICTS) +def test_the_same_record_computes_without_the_entitlement(name): + values = dict(ENTITLEMENT_CONFLICTS[name]) + month, counts = values.pop("month"), values.pop("counts") + values.pop("dib_entitlement_month") + person = _person(**values) + result = _computed( + person, + history(person, month, counts), + month, + test=i.InsuredTest.CURRENTLY, + ) + assert result.current_disability_period_start == person.disability_onset + assert result.currently.insured is False diff --git a/tests/test_track_b_insured_status_fix_round_2.py b/tests/test_track_b_insured_status_fix_round_2.py index 5f2341a44..d81e1720b 100644 --- a/tests/test_track_b_insured_status_fix_round_2.py +++ b/tests/test_track_b_insured_status_fix_round_2.py @@ -204,12 +204,21 @@ def test_continuous_onset_status_and_dli_equal_plain_quarter_scan( established = replace( person, current_disability_period_established=True ) - frozen = i.insured_status( - established, - history(established, month, counts), - month, - test=i.InsuredTest.DISABILITY, - ) + try: + frozen = i.insured_status( + established, + history(established, month, counts), + month, + test=i.InsuredTest.DISABILITY, + ) + except i.InsuredConfigurationUnsupported as error: + # Only a partial year can move the start away from one filling. + assert ( + error.reason + is i.InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY + ) + assert any(0 < count < 4 for count in counts.values()) + return expected_start = ( onset if quarters[0] == first else _quarter_date(quarters[0]) ) diff --git a/tests/test_track_b_insured_status_status_stress.py b/tests/test_track_b_insured_status_status_stress.py new file mode 100644 index 000000000..486bb4a05 --- /dev/null +++ b/tests/test_track_b_insured_status_status_stress.py @@ -0,0 +1,397 @@ +"""Seeded status stress on invented declarations in plain arithmetic. + +Verification class: statutory conformance; no population, behavioral or +forecast claim. This widens tests/test_track_b_insured_status_status_oracle.py +and calls only public declaration and result APIs. Its arithmetic imports no +production quarter, assignment, clock, requirement, witness or period helper. + +Space: women born 1940-1979, aged 31-58 at onset, onset from 1992, where Rule +I (20/40) or blindness applies. Endings, queries, annual totals with at most +four partial years, no prior, a clear prior or an overlapping prior, and +blindness in a quarter of cases all vary by seed. A second generator adds a +DIB entitlement month, which ends a CURRENTLY window before the onset. A third +draws ages 22-30 at onset, where 404.130(c) and (d) apply. Declared priors are +not re-adjudicated. No flags, UNKNOWN facts, DLI, subsequent-special routes, +raw earnings or death are claimed. + +Every annual placement and both all-prior treatments are enumerated. A lawful +filling has its own first insured start (404.321(a)), and that start supplies +the current period for FULLY and CURRENTLY. Each returned status must equal +the favorable Boolean over lawful fillings (RS 00301.230), and a true status +must hold on a filling whose first start is the reported start. A rejection +needs no lawful filling. A named refusal retains the declaration and passes. +""" + +import calendar +import random +from datetime import date, timedelta +from itertools import combinations, product + +import pytest +from hypothesis import example, given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as rule +from populace_dynamics.track_b.gross_benefits import InvalidFamilyInput + +# Seeds whose first start moved with placement. Round 14 answered each one +# from a start and a status that no single filling supports. +SPLIT_SEEDS = ( + 102037, + 102202, + 103045, + 103702, + 105793, + 109597, + 110777, + 203310, + 207027, + 207682, + 209481, + 209505, + 212010, +) + + +def quarter(day): + return day.year * 4 + (day.month - 1) // 3 + + +def usable(credits, at, periods): + """404.146(d): retain credited endpoints, remove strict interiors.""" + return { + credit + for credit in credits + if credit <= at + and not any(quarter(a) < credit < quarter(b) for a, b in periods) + } + + +def requirement(birth, at_year, periods): + first = max(1951, birth.year + 21 + 1) + last = min(at_year, birth.year + 62) + elapsed = sum( + not any(a.year <= year <= b.year for a, b in periods) + for year in range(first, last) + ) + return max(6, min(40, elapsed)) + + +def recent(use, at, periods, length): + """404.130(f): count back, keeping credited endpoint quarters.""" + seen = count = 0 + cursor = at + while seen < length: + excluded = any( + quarter(a) <= cursor <= quarter(b) and cursor not in use + for a, b in periods + ) + if not excluded: + seen += 1 + count += cursor in use + cursor -= 1 + return count + + +def under_31(birth, use, at, periods): + """404.130(c), (d): half the quarters after age 21, or 6 of 12.""" + attained_21 = quarter(date(birth.year + 21, birth.month, birth.day)) + if at >= quarter(date(birth.year + 31, birth.month, birth.day)): + return False + elapsed = [ + candidate + for candidate in range(attained_21 + 1, at + 1) + if not any( + quarter(a) <= candidate <= quarter(b) and candidate not in use + for a, b in periods + ) + ] + if len(elapsed) < 12: + return recent(use, at, periods, 12) >= 6 + credited = sum(candidate in use for candidate in elapsed[-40:]) + return credited >= max(6, min(len(elapsed), 40) // 2) + + +def disability(birth, credits, at, periods, blind): + use = usable(credits, at, periods) + fully = len(use) >= requirement(birth, at // 4, periods) + return fully and ( + blind + or recent(use, at, periods, 40) >= 20 + or under_31(birth, use, at, periods) + ) + + +def placements(annual): + options = [ + tuple(combinations(range(year * 4, year * 4 + 4), count)) + for year, count in annual.items() + ] + for pieces in product(*options): + yield frozenset(credit for piece in pieces for credit in piece) + + +def lawful_fillings(case): + """Exhaust every filling before comparing to a public result. + + Each lawful filling gives its first start and three statuses. + """ + birth, onset, ending, month = ( + case["birth"], + case["onset"], + case["ending"], + case["month"], + ) + blind, prior, annual = case["blind"], case["prior"], case["annual"] + at = quarter(month) + events = [ + event for event in (case.get("entitlement"),) if event is not None + ] or [month] + found = [] + for credits in placements(annual): + for use_prior in (True, False) if prior else (False,): + used = prior if use_prior else () + first = next( + ( + candidate + for candidate in range(quarter(onset), quarter(ending) + 1) + if disability(birth, credits, candidate, used, blind) + ), + None, + ) + if first is None or any( + quarter(a) <= first <= quarter(b) for a, b in prior + ): + continue + year, q = divmod(first, 4) + start = ( + onset if first == quarter(onset) else date(year, 3 * q + 1, 1) + ) + fully = currently = False + for periods in (prior + ((start, ending),), ()): + use = usable(credits, at, periods) + fully |= len(use) >= requirement(birth, month.year, periods) + currently |= any( + recent( + usable(credits, quarter(event), periods), + quarter(event), + periods, + 13, + ) + >= 6 + for event in events + ) + found.append( + ( + first, + fully, + currently, + any( + disability(birth, credits, candidate, used, blind) + for candidate in range(quarter(onset), at + 1) + ), + ) + ) + return found + + +def public(case): + observed = rule.EarningsProvenance.OBSERVED + person = rule.Person( + case["birth"], + sex=rule.Sex.FEMALE, + statutory_blindness=case["blind"], + disability_onset=case["onset"], + current_disability_period_established=True, + current_disability_period_provenance=observed, + current_disability_period_end=case["ending"], + current_disability_period_end_provenance=observed, + prior_disability_periods=tuple( + rule.DisabilityPeriod(a, b) for a, b in case["prior"] + ), + prior_disability_periods_provenance=observed, + sspa211_applies=False, + sspa211_provenance=observed, + dib_entitlement_month=case.get("entitlement"), + ) + years = { + year: ( + rule.CoverageYear(observed, qc_count=case["annual"].get(year, 0)) + if year >= 1978 + else rule.CoverageYear(observed, qc_quarters=(False,) * 4) + ) + for year in range(case["birth"].year, case["month"].year + 1) + } + return rule.insured_status(person, years, case["month"]) + + +def declaration(seed): + draw = random.Random(seed) + birth = date(draw.randint(1940, 1975), 2, 2) + year = birth.year + draw.randint(31, 58) + if year < 1992: + year = draw.randint(1992, 2010) + if not 31 <= year - birth.year <= 58: + birth = date(year - draw.randint(31, 58), 2, 2) + onset = date(year, draw.choice((1, 2, 3, 4, 5, 7, 8, 10, 11, 12)), 15) + ending_year = year + draw.choice((0, 0, 1, 2, 3)) + ending_month = draw.randint(12 if ending_year == year else 1, 12) + ending = date( + ending_year, + ending_month, + calendar.monthrange(ending_year, ending_month)[1], + ) + if draw.random() < 0.3: + ending = date(ending_year, 12, 31) + month = date(ending.year + draw.choice((1, 1, 2, 4, 9)), 1, 1) + if month.year - birth.year > 62: + month = date(ending.year + 1, 1, 1) + annual = {} + span = draw.randint(5, 16) + density = draw.choice((0.5, 0.7, 0.85, 1.0)) + first = max(1978, year - span) + for credited in range(first, year): + if draw.random() < density: + annual[credited] = 4 + for credited in draw.sample(range(first, ending.year + 1), k=3): + annual[credited] = draw.randint(1, 3) + if draw.random() < 0.5: + annual[year] = draw.randint(1, 3) + for credited in range(year + 1, month.year): + if draw.random() < 0.3: + annual[credited] = draw.randint(0, 4) + annual = {y: n for y, n in annual.items() if n and y < month.year} + for credited in [y for y, n in annual.items() if n < 4][4:]: + annual[credited] = 4 + kind = draw.choice(("none", "clear", "overlap", "overlap")) + prior = () + if kind != "none": + begins = date(year - draw.randint(1, 4), draw.choice((1, 4, 7, 10)), 1) + if kind == "clear": + ends = date(year - 1, 12, 31) + if begins < ends: + prior = ((begins, ends),) + elif onset.month % 3 != 1: + first_day = date(year, 3 * ((onset.month - 1) // 3) + 1, 1) + ends = first_day + timedelta(days=draw.randint(0, 20)) + if ends < onset: + prior = ((begins, ends),) + return { + "birth": birth, + "onset": onset, + "ending": ending, + "month": month, + "blind": draw.random() < 0.25, + "prior": prior, + "annual": annual, + } + + +def with_entitlement(seed): + """Date a DIB entitlement in a partial year up to the onset, mostly.""" + case = declaration(seed) + draw = random.Random(f"entitlement-{seed}") + onset_year = case["onset"].year + partial = [ + year + for year, count in case["annual"].items() + if count < 4 and year <= onset_year + ] + if partial and draw.random() < 0.8: + year = draw.choice(partial) + else: + year = draw.randint(onset_year - 12, onset_year) + case["entitlement"] = date( + year, draw.choice((1, 2, 4, 5, 7, 8, 10, 11)), 1 + ) + return case + + +def under_31_declaration(seed): + draw = random.Random(f"under-31-{seed}") + # Onset from 1981 keeps every ending past 404.321(b)'s implied recovery. + birth = date(draw.randint(1959, 1985), 2, 2) + year = birth.year + draw.randint(22, 30) + onset = date(year, draw.choice((1, 2, 3, 4, 5, 7, 8, 10, 11, 12)), 15) + ending_year = year + draw.choice((1, 2, 3)) + ending_month = draw.randint(1, 12) + ending = date( + ending_year, + ending_month, + calendar.monthrange(ending_year, ending_month)[1], + ) + month = date(ending.year + draw.choice((1, 1, 2, 4)), 1, 1) + annual = {} + for credited in range(max(1978, birth.year + 16), year + 1): + if draw.random() < 0.8: + annual[credited] = draw.choice((1, 2, 3, 3, 4, 4)) + for credited in range(year + 1, month.year): + if draw.random() < 0.25: + annual[credited] = draw.randint(1, 4) + for credited in [y for y, n in annual.items() if n < 4][4:]: + annual[credited] = 4 + return { + "birth": birth, + "onset": onset, + "ending": ending, + "month": month, + "blind": False, + "prior": (), + "annual": annual, + } + + +def check(case): + fillings = lawful_fillings(case) + try: + result = public(case) + except rule.InsuredConfigurationUnsupported: + return "refused" + except InvalidFamilyInput as error: + assert not fillings, (case, error) + return "invalid" + assert fillings, (case, "computed an impossible establishment", result) + actual = tuple( + getattr(result, name).insured + for name in ("fully", "currently", "disability") + ) + expected = tuple( + any(filling[index] for filling in fillings) for index in (1, 2, 3) + ) + assert actual == expected, (case, actual, expected, result) + start = quarter(result.current_disability_period_start) + for index, insured in enumerate(actual, 1): + assert not insured or any( + filling[0] == start and filling[index] for filling in fillings + ), (case, actual, start, fillings) + return "computed" + + +@pytest.mark.parametrize("seed", SPLIT_SEEDS) +def test_status_stress_refuses_a_start_no_filling_supports(seed): + with pytest.raises(rule.InsuredConfigurationUnsupported) as error: + public(declaration(seed)) + assert ( + error.value.reason + is rule.InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY + ) + + +@settings(max_examples=120, deadline=None, derandomize=True) +@example(seed=103702) +@example(seed=207682) +@given(seed=st.integers(0, 2**32 - 1)) +def test_status_stress_matches_the_favorable_filling(seed): + check(declaration(seed)) + + +@settings(max_examples=120, deadline=None, derandomize=True) +@given(seed=st.integers(0, 2**32 - 1)) +def test_status_stress_with_an_entitlement_month(seed): + check(with_entitlement(seed)) + + +@settings(max_examples=120, deadline=None, derandomize=True) +@given(seed=st.integers(0, 2**32 - 1)) +def test_status_stress_under_31(seed): + check(under_31_declaration(seed)) diff --git a/tests/tier_counts.json b/tests/tier_counts.json index afcddd004..3961eebd6 100644 --- a/tests/tier_counts.json +++ b/tests/tier_counts.json @@ -1,7 +1,7 @@ { "schema_version": 1, "counts": { - "unit": 21273, + "unit": 21336, "artifact": 4271, "integration_psid": 1471, "reproduction_legacy": 520, From e9f4140c379e3223bc9fcadf07da675b6dfe5159 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sun, 1 Nov 2026 06:16:20 -0500 Subject: [PATCH 22/46] Track B insured status: hold exact diagnostics to the reported start Sol's eleventh review of c28bb1dd found two mediums, and both reproduced. - Round 15 joined each status's Boolean to the reported first start, but its count and assignment kept the status's own favorable placement. A record whose 2000 QC must sit in 2000Q2 or later reported seven of 13 with that QC in 2000Q1, where every lawful filling finds six. _settle_first_start now searches on for each status's best witness among fillings that keep the reported start. The year counts and top-level assignment describe the returned filling. - _last_insured returned no date below six ordinary QCs, so a blind record lost the date Act 213(c)'s aggregate could supply. That row now refuses by name. Surviving mutations found three more gaps, and tests now close them: an ending the reported start can't meet, a date only a moved placement reaches, and year counts that left the returned filling. A fourth survivor showed the first version of the fix reported an arbitrary filling, so the search now tries the excluded world's credited quarters after the start's witness. A fifth showed an unknown current period can't reach this step, so that condition is gone. Both status oracles now check counts and the date last insured, and they draw the subsequent-special route. The round 15 test that had $8,700 computing false now refuses, because 21 credits meet 1972's 21 for a historical date. No reading changes. No gate, loop, step or run artifact changes. Invariants: a computed count and assignment rest on a filling whose own first start is the reported start; each period ending and the date last insured must hold at that start; a fixed start and an UNKNOWN envelope keep their favorable or outer counts; year counts equal the returned filling's credits on exact rows; candidate order changes no output; a date last insured below six ordinary QCs refuses exactly where the aggregate reaches six. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 150 ++++- .../track_b_insured_status_mutations.json | 518 ++++++++++++++++- .../track_b/insured_status.py | 228 +++++--- tests/README-tiers.md | 4 +- ...est_track_b_insured_status_fix_round_15.py | 11 +- ...est_track_b_insured_status_fix_round_16.py | 521 ++++++++++++++++++ ...st_track_b_insured_status_status_oracle.py | 64 ++- ...st_track_b_insured_status_status_stress.py | 180 +++++- tests/tier_counts.json | 2 +- 9 files changed, 1570 insertions(+), 108 deletions(-) create mode 100644 tests/test_track_b_insured_status_fix_round_16.py diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index 597b8f5d4..888dd5eeb 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -470,6 +470,8 @@ each earnings-bound world. Thus a disability witness can show 20 recent QCs and still be uninsured because its duration-of-work requirement is not met. The low and high witnesses each optimize assignment for that particular test. They need not have the same assignment or prior-period treatment. +Where the first start can move, each keeps a filling with the reported start, +and `qcs_by_year` and the top-level assignment describe the returned filling. The per-year QC mapping uses the disability-excluded context; the witness identifies credits actually used if disregarding the periods is favorable. Witness fields describe selected computations; their endpoint counts are @@ -854,7 +856,7 @@ to a statutory sentence that does not state it. | B14. Declaring continuity never widens the administrative-end candidate set; every returned status and count envelope remains valid for every retained concrete ending. | C321(c)'s ending events still govern. Set intersection with ends on/after the observation can only remove candidates; it creates neither an ending nor a new credit. The universal envelope remains unchanged where other unknown facts require it. | | B15. Ordinary establishment overlap resolution enumerates at most 4,096 unknown-credit fillings after its fixed-date monotonicity, candidate-quarter, six-QC, and minimum-requirement proofs. | C320(b)(2) and C321(a) require one insured beginning consistent with the complete declaration. I13 settles fixed-quarter overlap and I15 settles a known-history nonblind lifetime-QC shortfall before enumeration. If neither settles the declaration, a search beyond the limit returns `disability_boundary_assignments_unsupported`; it asserts neither a concrete filling nor an input error. | | B16. A deferred raw-conversion row retains independently computable ordinary credits in its minimum and every enumerated filling, and cannot exceed feasible calendar-quarter credits in its maximum. | A213(d)(2)'s prior-increment floor bounds future annual credits above by the captured 2027 increment applied to the supplied wages plus SE income; the possibility-only lower bound is zero. Raw 1937 allocation remains zero through four because A213(b)'s half-year rule is unresolved. For separate pre1955 agriculture or pre1951 SE, supported quarterly wage credits and supported post1950 calendar-year SE credits remain fixed; unresolved additional allocation can fill only remaining allowed quarters. Both minimum and maximum fillings may violate derived overlap even when a middle filling is valid, so neither endpoint alone proves impossibility. These bounds do not adjudicate a specialist allocation or replace its refusal. | -| B17. The first-start check refuses when flexible credits allow a better result at any possible start, and it searches at most 4,096 placements of the annual years that can change a first insured quarter. | 404.321(a) gives a record one start, and RS .230 makes placement flexible. A year wholly inside every tested window and untouched by a period adds its full count wherever its QCs fall, so it stays flexible. Without prior periods, an insured worst filling proves no filling starts later, and the check stops. The bound can refuse a declaration that no concrete filling improves, and a search can reach its limit before it attains a result. Both return `disability_boundary_assignments_unsupported`, so the row keeps its weight; neither asserts a filling or an input error. | +| B17. The first-start check refuses when flexible credits allow a better result at any possible start, and it searches at most 4,096 placements of the annual years that can change a first insured quarter. | 404.321(a) gives a record one start, and RS .230 makes placement flexible. A year wholly inside every tested window and untouched by a period adds its full count wherever its QCs fall, so it stays flexible. Without prior periods, an insured worst filling proves no filling starts later, and the check stops. The bound can refuse a declaration that no concrete filling improves, and a search can reach its limit before it attains a result. Round 16's longer search for each status's witness can reach the same limit. All return `disability_boundary_assignments_unsupported`, so the row keeps its weight; none asserts a filling or an input error. | The round-5 adversarial audit revisits each row in both directions in `scratch/review/round5-premise-audit.md`: a valid filling cannot be rejected, @@ -1922,7 +1924,8 @@ status or a later date last insured refuses the row with `disability_boundary_assignments_unsupported`. It then looks for an attaining filling, starting from the filling that insures the reported start and varying the latest years first, because those years conflict -with the later windows. The first attaining filling ends the search. A year +with the later windows. Round 15 stopped at the first attaining filling, and +round 16 searches on for each status's count. A year that can't move the start stays flexible, so each status still places it favorably. The check joins each status to the start, not the statuses to one another. This keeps the favorable answer of RS 00301.230 and replaces an @@ -1961,8 +1964,9 @@ found 13 status disagreements and no false rejection, and each of the 13 had more than one possible first start. The committed test pins all 13 seeds and generates more. Two more generators add a DIB entitlement month, drawn mostly from partial years up to the onset, and ages 22 to 30 at onset -under 404.130(c) and (d). DLI, the subsequent-special route, UNKNOWN facts -and flags stay outside its claim. Declared priors are not re-adjudicated. +under 404.130(c) and (d). UNKNOWN facts and flags stay outside its claim, +and round 16 adds the date last insured and the subsequent-special route. +Declared priors are not re-adjudicated. After the fix, the same 28,000 and 14,000 fresh declarations give no disagreement, no false rejection and no computed row without a lawful @@ -2004,6 +2008,144 @@ The invariants added in this round are executed by these tests: - the DISABILITY refusal tracks the exact aggregate (`test_disability_refusal_tracks_the_exact_aggregate`). +## Round 16 diagnostics on the reported start + +Verification class: statutory conformance on invented declarations only. +This correction admits no population, behavioral, payment, or forecast claim. +Sol's eleventh review of `c28bb1dd` raised two mediums, and both reproduced. + +### Exact diagnostics rest on the reported start + +Round 15 joined each status's Boolean to the reported start. Its count and +assignment kept the status's own favorable placement, so an exact diagnostic +could describe a filling that 404.321(a) excludes. An invented woman born +1962-02-02 has annual QCs 1998:4, 1999:2, 2000:1, four in each of 2001 to +2004 and 2005:3, onset 2010-01-15, a period ending 2010-12-31 and a DIB +entitlement month of 2000-01. The 2000 QC reaches 20 of 40 at the onset only +in 2000Q2 or later, so every lawful filling finds six of 13 at the entitlement +month. At `c28bb1dd` CURRENTLY reported seven, and both its assignment and +the top-level `assigned_quarters` put that QC in 2000Q1. The status stayed +true, and the count and quarter were wrong. The review's record adds a prior +period and earlier work, with the same result. + +`_settle_first_start` now takes each status's witness for each period ending. +It searches past the first attaining filling until every witness recurs with +the reported start or the placements run out. It then returns the filling +that attained the result and each status's best witness among the fillings +that keep the reported start. `_witness_rank` orders them as `_witness` +scores them, by status, then margin over the requirement, then count. Every +ending must still agree once its witness keeps the reported start, and a +status only a moved placement met keeps its +`disability_boundary_assignments_unsupported` refusal. The top-level +`assigned_quarters` and `qcs_by_year` describe the returned filling. Where +the same record has no moving start, `_start_fixed` holds and each status +keeps its own favorable placement. So does an UNKNOWN year or prior, whose +envelope states an outer bound rather than a filling. This changes no reading. It carries the logged reading +`us:oasdi-insured-one-filling-first-start` from the Boolean to the fields +that report it. + +Three records pin the edges. With nineteen QCs through 1999, one 2000 QC, an +onset of 1999-06-15 and a query of 2003-04-01, a declared ending in 2000Q2 or +later meets CURRENTLY at the reported start with the 2000 QC in 2000Q1. An +ending in 2000Q1 needs that QC in a later quarter, so it refuses. An UNKNOWN +ending includes that one, so it refuses too, although its other endings +agree. With 19 QCs from 2001 through 2005, the latest date last insured needs +the 2000 QC in 2000Q2 or later and the row refuses. With 20, the date doesn't +need that QC, and it computes 2010-12-31. + +The returned filling is one lawful filling, not a proof that it credits the +most quarters. The search tries the start's witness first and then the +quarters `_world` credits in the excluded context, so a year keeps its +credits where it can. A disregard-periods witness can still hold a year's QCs +inside a prior, and the year count then falls below what another filling with +the same start gives. This limit touches only that diagnostic: no status, +count, start or date depends on it, and no module reads `qcs_by_year` or the +top-level `assigned_quarters`. An exact row keeps +`qcs_by_year[y] == (len(assigned_quarters[y]),) * 2`. + +Sol's record moves a count, and the random generators rarely reach one. On +1,200 stress declarations, `c28bb1dd` and this head agree on every outcome +class, status, count, start and date, and 67 rows change only where their QCs +sit. The exhaustive placements in +`test_a_computed_count_is_the_best_lawful_count` check the rule's count against +plain arithmetic for the no-prior record, and each stress generator now checks +counts on every computed row. + +### The aggregate below six ordinary QCs + +`_last_insured` returned no date last insured below six ordinary QCs, on the +premise that every route needs them. A blind person's fully insured route +doesn't: blindness removes the recent rule, and Act 213(c)'s aggregate can +supply the fully insured quarters. An invented blind woman born 1926-02-02 has $8,800 in +single quarters across 1948 to 1950 and three ordinary QCs. Her 22 aggregate +credits match the 22 of 1973, so at 1974-01-01 the aggregate could date her +last insured quarter, while `c28bb1dd` reported none. The row now refuses +with `simplified_pre1951_unsupported`, with or without an exit. The same +holds for 52 quarters of $49, which earn no ordinary QC. The shortcut still +answers every nonblind record, because each nonblind route needs six ordinary +QCs in its own window. A blind record with no wages reaches the scan and finds +no date. + +`test_blind_aggregate_decides_below_six_ordinary_qcs` in round 15 asserted +that $8,700, or 21 credits, computed false. Those credits meet 1972's 21 for a +historical date, so that row now refuses, and $2,397, or five credits, takes +its place as the row that computes. + +### Oracle reach and bounds + +The status oracle and stress generators drew neither the date last insured nor +the subsequent-special route, and they checked no count. Both claims now +execute. `favorable_statuses` and `lawful_fillings` return each lawful +filling's own first start, and `_check_diagnostics` and `check_diagnostics` +hold every computed count and date to the best filling with the reported +start. `subsequent_declaration` draws a special prior from ages 24 to 30 and +an onset from ages 32 to 40, so 404.130(d) now runs alongside 404.130(c). +The session drew 4,800 fresh declarations across the four generators at the +final source. Of these, 3,131 computed and agreed on status, count and date, 62 +refused by name, 1,607 raised `InvalidFamilyInput` with no lawful filling, and +nothing disagreed. + +Ten mutations survived a first pass, and execution settled each one. Eight +were test gaps, and named tests now kill them. The first fix returned the first +attaining filling, and a differential against `c28bb1dd` found that it lowered +the year count in 62 of 712 computed rows. The `favored` tie-break brings +that to 8. Reversing every candidate list changes no output on those +declarations. Without the sort's last key, the same reversal changes 72. +`unknown_current_treated_as_exact` showed that an UNKNOWN current period can't +reach `_settle_first_start`, because its start stays `None`, so that condition +left the code. `rank_ignores_status` is equivalent: the search ranks only +FULLY and CURRENTLY witnesses, whose `insured` is exactly `count >= required`, +and all 9,892 witnesses ranked in a stress run agree. All 23 mutations in the +ledger ran against the final source, with 22 killed and that one equivalent. + +The longer search can reach the 4,096 limit where the first attaining +filling once stopped it. Such a row refuses by name and keeps its weight, as +B17 records. + +The invariants added in this round are executed by these tests: + +- a computed count and assignment rest on a filling with the reported start + (`test_count_and_assignment_keep_the_reported_start`, + `test_every_exact_diagnostic_rests_on_one_filling`, + `test_a_computed_count_is_the_best_lawful_count`, and both oracles); +- a fixed start and an UNKNOWN envelope keep the favorable count + (`test_a_fixed_start_keeps_the_favorable_count`, + `test_unknown_years_keep_the_universal_envelope`, + `test_an_unknown_ending_keeps_each_endings_witness`); +- the year counts match the returned filling + (`test_status_stress_year_counts_follow_the_returned_filling`, + `check_diagnostics`), and that filling keeps credited endpoints + (`test_status_stress_returned_filling_keeps_credited_endpoints`); +- each ending must hold at the reported start, and so must the date last + insured (`test_an_ending_the_reported_start_fails_refuses`, + `test_a_later_ending_meets_currently_at_the_reported_start`, + `test_a_date_only_a_moved_placement_reaches_refuses`, + `test_a_date_the_reported_start_reaches_computes`); +- a date last insured below six ordinary QCs refuses exactly where the + aggregate reaches six or more (`test_the_dli_refusal_tracks_six_aggregate_qcs`, + `test_aggregate_below_six_ordinary_qcs_refuses_the_dli`, + `test_aggregate_with_no_ordinary_qc_refuses_the_dli`). + ## Not in scope No real data, population evaluation, baseline claiming hazard, behavioral diff --git a/docs/design/track_b_insured_status_mutations.json b/docs/design/track_b_insured_status_mutations.json index 0a4d7419c..88baaef26 100644 --- a/docs/design/track_b_insured_status_mutations.json +++ b/docs/design/track_b_insured_status_mutations.json @@ -5313,5 +5313,521 @@ "tests/test_track_b_insured_status_status_oracle.py": "4b603ca88ea6b52e518dcc93ef08d67ed49f7604aa1894a3b50baedf47aa2b61" }, "round_15_replay": "Write round_15_runner_source to scratch/review/run_round15_named.py. For each round_15_mutations record, write name/source_sha256/changes to its spec_path, then execute its exact command. Mutations apply only in memory.", - "round_15_final_source_sha256": "474239bd8216a942e55c462b43a441a23abc8b96ed820ddb02de53c60b266beb" + "round_15_final_source_sha256": "474239bd8216a942e55c462b43a441a23abc8b96ed820ddb02de53c60b266beb", + "round_16_mutations": [ + { + "name": "restore_six_qc_shortcut", + "source_sha256": "3fed28da694474236b63ff99a1d42576994de87a81297ba6f416f4d6fdd2a25e", + "changes": [ + { + "before": " if years is None or not person.statutory_blindness:\n return None, False\n", + "after": " return None, False\n" + } + ], + "spec_path": "scratch/review/round16-mutation-restore_six_qc_shortcut.json", + "log": "scratch/review/round16-mutation-restore_six_qc_shortcut.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round16 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round16 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND16_MUTATION=scratch/review/round16-mutation-restore_six_qc_shortcut.json .venv/bin/python scratch/review/run_round16_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_16.py::test_aggregate_below_six_ordinary_qcs_refuses_the_dli[None-1974-InsuredTest.DISABILITY]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "empty_credit_scan_skipped", + "source_sha256": "3fed28da694474236b63ff99a1d42576994de87a81297ba6f416f4d6fdd2a25e", + "changes": [ + { + "before": "min(credited_years, default=1937)", + "after": "min(credited_years, default=3000)" + } + ], + "spec_path": "scratch/review/round16-mutation-empty_credit_scan_skipped.json", + "log": "scratch/review/round16-mutation-empty_credit_scan_skipped.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round16 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round16 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND16_MUTATION=scratch/review/round16-mutation-empty_credit_scan_skipped.json .venv/bin/python scratch/review/run_round16_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_16.py::test_aggregate_with_no_ordinary_qc_refuses_the_dli" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "reported_never_exact", + "source_sha256": "3fed28da694474236b63ff99a1d42576994de87a81297ba6f416f4d6fdd2a25e", + "changes": [ + { + "before": " None\n if unknown or prior_unknown\n else tuple(candidates[kind] for kind in kinds)\n", + "after": " None\n" + } + ], + "spec_path": "scratch/review/round16-mutation-reported_never_exact.json", + "log": "scratch/review/round16-mutation-reported_never_exact.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round16 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round16 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND16_MUTATION=scratch/review/round16-mutation-reported_never_exact.json .venv/bin/python scratch/review/run_round16_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_16.py::test_count_and_assignment_keep_the_reported_start[None-2011-InsuredTest.CURRENTLY-no-prior]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "settled_not_applied", + "source_sha256": "3fed28da694474236b63ff99a1d42576994de87a81297ba6f416f4d6fdd2a25e", + "changes": [ + { + "before": " decisions[kind] = _status_decision(witnesses, witnesses)\n", + "after": " pass\n" + } + ], + "spec_path": "scratch/review/round16-mutation-settled_not_applied.json", + "log": "scratch/review/round16-mutation-settled_not_applied.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round16 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round16 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND16_MUTATION=scratch/review/round16-mutation-settled_not_applied.json .venv/bin/python scratch/review/run_round16_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_16.py::test_count_and_assignment_keep_the_reported_start[None-2011-InsuredTest.CURRENTLY-no-prior]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "placement_not_in_assignment", + "source_sha256": "3fed28da694474236b63ff99a1d42576994de87a81297ba6f416f4d6fdd2a25e", + "changes": [ + { + "before": " lo_person,\n placement or lower,\n", + "after": " lo_person,\n lower,\n" + } + ], + "spec_path": "scratch/review/round16-mutation-placement_not_in_assignment.json", + "log": "scratch/review/round16-mutation-placement_not_in_assignment.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round16 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round16 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND16_MUTATION=scratch/review/round16-mutation-placement_not_in_assignment.json .venv/bin/python scratch/review/run_round16_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_16.py::test_every_exact_diagnostic_rests_on_one_filling[no-prior]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "placement_not_in_year_counts", + "source_sha256": "3fed28da694474236b63ff99a1d42576994de87a81297ba6f416f4d6fdd2a25e", + "changes": [ + { + "before": " (lo_completions, placement or lower),\n (hi_completions, placement or upper),\n", + "after": " (lo_completions, lower),\n (hi_completions, upper),\n" + } + ], + "spec_path": "scratch/review/round16-mutation-placement_not_in_year_counts.json", + "log": "scratch/review/round16-mutation-placement_not_in_year_counts.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round16 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round16 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND16_MUTATION=scratch/review/round16-mutation-placement_not_in_year_counts.json .venv/bin/python scratch/review/run_round16_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_year_counts_follow_the_returned_filling[5000026]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "keep_worst_witness", + "source_sha256": "3fed28da694474236b63ff99a1d42576994de87a81297ba6f416f4d6fdd2a25e", + "changes": [ + { + "before": " max(entries, key=_witness_rank)\n", + "after": " min(entries, key=_witness_rank)\n" + } + ], + "spec_path": "scratch/review/round16-mutation-keep_worst_witness.json", + "log": "scratch/review/round16-mutation-keep_worst_witness.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round16 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round16 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND16_MUTATION=scratch/review/round16-mutation-keep_worst_witness.json .venv/bin/python scratch/review/run_round16_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_status_oracle.py::test_status_oracle_completion_lattice[2-claiming-none-False]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "rank_ignores_margin", + "source_sha256": "3fed28da694474236b63ff99a1d42576994de87a81297ba6f416f4d6fdd2a25e", + "changes": [ + { + "before": " return witness[0], witness[1] - witness[2], witness[1]\n", + "after": " return witness[0], witness[1]\n" + } + ], + "spec_path": "scratch/review/round16-mutation-rank_ignores_margin.json", + "log": "scratch/review/round16-mutation-rank_ignores_margin.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round16 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round16 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND16_MUTATION=scratch/review/round16-mutation-rank_ignores_margin.json .venv/bin/python scratch/review/run_round16_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_status_oracle.py::test_status_oracle_completion_lattice[3-after-clear-False]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "rank_ignores_status", + "source_sha256": "3fed28da694474236b63ff99a1d42576994de87a81297ba6f416f4d6fdd2a25e", + "changes": [ + { + "before": " return witness[0], witness[1] - witness[2], witness[1]\n", + "after": " return witness[1] - witness[2], witness[1]\n" + } + ], + "spec_path": "scratch/review/round16-mutation-rank_ignores_status.json", + "log": "scratch/review/round16-mutation-rank_ignores_status.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round16 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round16 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND16_MUTATION=scratch/review/round16-mutation-rank_ignores_status.json .venv/bin/python scratch/review/run_round16_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 0, + "failing_test_nodes": [], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "stop_at_first_joint_filling", + "source_sha256": "3fed28da694474236b63ff99a1d42576994de87a81297ba6f416f4d6fdd2a25e", + "changes": [ + { + "before": " if joint is not None and _witness_ranks(kept) == _witness_ranks(\n reported\n ):\n return joint, kept\n", + "after": " if joint is not None:\n return joint, kept\n" + } + ], + "spec_path": "scratch/review/round16-mutation-stop_at_first_joint_filling.json", + "log": "scratch/review/round16-mutation-stop_at_first_joint_filling.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round16 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round16 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND16_MUTATION=scratch/review/round16-mutation-stop_at_first_joint_filling.json .venv/bin/python scratch/review/run_round16_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_16.py::test_an_ending_the_reported_start_fails_refuses[unknown-ending]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "never_stop_early", + "source_sha256": "3fed28da694474236b63ff99a1d42576994de87a81297ba6f416f4d6fdd2a25e", + "changes": [ + { + "before": " if joint is not None and _witness_ranks(kept) == _witness_ranks(\n reported\n ):\n return joint, kept\n", + "after": "" + } + ], + "spec_path": "scratch/review/round16-mutation-never_stop_early.json", + "log": "scratch/review/round16-mutation-never_stop_early.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round16 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round16 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND16_MUTATION=scratch/review/round16-mutation-never_stop_early.json .venv/bin/python scratch/review/run_round16_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_15.py::test_a_moving_start_keeps_a_result_one_filling_attains" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "drop_ending_agreement", + "source_sha256": "3fed28da694474236b63ff99a1d42576994de87a81297ba6f416f4d6fdd2a25e", + "changes": [ + { + "before": " if joint is None or any(\n entry[0][0] != insured\n for entries, insured in zip(kept, returned, strict=True)\n for entry in entries\n ):\n", + "after": " if joint is None:\n" + } + ], + "spec_path": "scratch/review/round16-mutation-drop_ending_agreement.json", + "log": "scratch/review/round16-mutation-drop_ending_agreement.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round16 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round16 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND16_MUTATION=scratch/review/round16-mutation-drop_ending_agreement.json .venv/bin/python scratch/review/run_round16_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_16.py::test_an_ending_the_reported_start_fails_refuses[unknown-ending]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "drop_unattained_refusal", + "source_sha256": "3fed28da694474236b63ff99a1d42576994de87a81297ba6f416f4d6fdd2a25e", + "changes": [ + { + "before": " if joint is None or any(\n entry[0][0] != insured\n for entries, insured in zip(kept, returned, strict=True)\n for entry in entries\n ):\n", + "after": " if False:\n" + } + ], + "spec_path": "scratch/review/round16-mutation-drop_unattained_refusal.json", + "log": "scratch/review/round16-mutation-drop_unattained_refusal.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round16 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round16 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND16_MUTATION=scratch/review/round16-mutation-drop_unattained_refusal.json .venv/bin/python scratch/review/run_round16_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_16.py::test_a_status_only_the_moved_placement_met_refuses" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "outcome_ignores_dli", + "source_sha256": "3fed28da694474236b63ff99a1d42576994de87a81297ba6f416f4d6fdd2a25e", + "changes": [ + { + "before": " outcome[:2] == (returned, last_insured) for outcome in outcomes\n", + "after": " outcome[0] == returned for outcome in outcomes\n" + } + ], + "spec_path": "scratch/review/round16-mutation-outcome_ignores_dli.json", + "log": "scratch/review/round16-mutation-outcome_ignores_dli.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round16 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round16 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND16_MUTATION=scratch/review/round16-mutation-outcome_ignores_dli.json .venv/bin/python scratch/review/run_round16_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_16.py::test_a_date_only_a_moved_placement_reaches_refuses[InsuredTest.DISABILITY]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "own_start_not_required", + "source_sha256": "3fed28da694474236b63ff99a1d42576994de87a81297ba6f416f4d6fdd2a25e", + "changes": [ + { + "before": " if own_start != start:\n continue\n outcomes = tuple(", + "after": " outcomes = tuple(" + } + ], + "spec_path": "scratch/review/round16-mutation-own_start_not_required.json", + "log": "scratch/review/round16-mutation-own_start_not_required.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round16 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round16 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND16_MUTATION=scratch/review/round16-mutation-own_start_not_required.json .venv/bin/python scratch/review/run_round16_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_16.py::test_an_ending_the_reported_start_fails_refuses[unknown-ending]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "unknown_years_treated_as_exact", + "source_sha256": "3fed28da694474236b63ff99a1d42576994de87a81297ba6f416f4d6fdd2a25e", + "changes": [ + { + "before": " if unknown or prior_unknown\n", + "after": " if prior_unknown\n" + } + ], + "spec_path": "scratch/review/round16-mutation-unknown_years_treated_as_exact.json", + "log": "scratch/review/round16-mutation-unknown_years_treated_as_exact.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round16 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round16 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND16_MUTATION=scratch/review/round16-mutation-unknown_years_treated_as_exact.json .venv/bin/python scratch/review/run_round16_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_16.py::test_unknown_years_keep_the_universal_envelope[InsuredTest.FULLY-fully]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "unknown_priors_treated_as_exact", + "source_sha256": "3fed28da694474236b63ff99a1d42576994de87a81297ba6f416f4d6fdd2a25e", + "changes": [ + { + "before": " if unknown or prior_unknown\n", + "after": " if unknown\n" + } + ], + "spec_path": "scratch/review/round16-mutation-unknown_priors_treated_as_exact.json", + "log": "scratch/review/round16-mutation-unknown_priors_treated_as_exact.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round16 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round16 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND16_MUTATION=scratch/review/round16-mutation-unknown_priors_treated_as_exact.json .venv/bin/python scratch/review/run_round16_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_16.py::test_unknown_priors_keep_the_universal_envelope" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "drop_canonical_tie", + "source_sha256": "3fed28da694474236b63ff99a1d42576994de87a81297ba6f416f4d6fdd2a25e", + "changes": [ + { + "before": " len(set(choice) - favored),\n choice,\n", + "after": " len(set(choice) - favored),\n" + } + ], + "spec_path": "scratch/review/round16-mutation-drop_canonical_tie.json", + "log": "scratch/review/round16-mutation-drop_canonical_tie.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round16 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round16 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND16_MUTATION=scratch/review/round16-mutation-drop_canonical_tie.json .venv/bin/python scratch/review/run_round16_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_candidate_order_changes_nothing[5000019]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "favored_ignored", + "source_sha256": "3fed28da694474236b63ff99a1d42576994de87a81297ba6f416f4d6fdd2a25e", + "changes": [ + { + "before": " len(set(choice) - favored),\n", + "after": "" + } + ], + "spec_path": "scratch/review/round16-mutation-favored_ignored.json", + "log": "scratch/review/round16-mutation-favored_ignored.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round16 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round16 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND16_MUTATION=scratch/review/round16-mutation-favored_ignored.json .venv/bin/python scratch/review/run_round16_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_returned_filling_keeps_credited_endpoints" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "witness_order_ignored", + "source_sha256": "3fed28da694474236b63ff99a1d42576994de87a81297ba6f416f4d6fdd2a25e", + "changes": [ + { + "before": " len(set(choice) - witness),\n", + "after": "" + } + ], + "spec_path": "scratch/review/round16-mutation-witness_order_ignored.json", + "log": "scratch/review/round16-mutation-witness_order_ignored.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round16 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round16 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND16_MUTATION=scratch/review/round16-mutation-witness_order_ignored.json .venv/bin/python scratch/review/run_round16_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_15.py::test_a_moving_start_keeps_a_result_one_filling_attains" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "envelope_dropped", + "source_sha256": "3fed28da694474236b63ff99a1d42576994de87a81297ba6f416f4d6fdd2a25e", + "changes": [ + { + "before": " lo_candidates, hi_candidates, maximum_qcs if broad else None\n", + "after": " lo_candidates, hi_candidates\n" + } + ], + "spec_path": "scratch/review/round16-mutation-envelope_dropped.json", + "log": "scratch/review/round16-mutation-envelope_dropped.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round16 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round16 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND16_MUTATION=scratch/review/round16-mutation-envelope_dropped.json .venv/bin/python scratch/review/run_round16_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_16.py::test_unknown_years_keep_the_universal_envelope[InsuredTest.FULLY-fully]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "full_count_ignores_envelope", + "source_sha256": "3fed28da694474236b63ff99a1d42576994de87a81297ba6f416f4d6fdd2a25e", + "changes": [ + { + "before": " (0, envelope, 0, envelope)\n", + "after": " (0, envelope, witnesses[0][7], witnesses[0][7])\n" + } + ], + "spec_path": "scratch/review/round16-mutation-full_count_ignores_envelope.json", + "log": "scratch/review/round16-mutation-full_count_ignores_envelope.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round16 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round16 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND16_MUTATION=scratch/review/round16-mutation-full_count_ignores_envelope.json .venv/bin/python scratch/review/run_round16_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_16.py::test_unknown_years_keep_the_universal_envelope[InsuredTest.FULLY-fully]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "decision_swaps_lo_hi", + "source_sha256": "3fed28da694474236b63ff99a1d42576994de87a81297ba6f416f4d6fdd2a25e", + "changes": [ + { + "before": " lo, lo_quarter = lo_candidates[-1]\n hi, hi_quarter = hi_candidates[0]\n", + "after": " lo, lo_quarter = lo_candidates[0]\n hi, hi_quarter = hi_candidates[-1]\n" + } + ], + "spec_path": "scratch/review/round16-mutation-decision_swaps_lo_hi.json", + "log": "scratch/review/round16-mutation-decision_swaps_lo_hi.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round16 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round16 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND16_MUTATION=scratch/review/round16-mutation-decision_swaps_lo_hi.json .venv/bin/python scratch/review/run_round16_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_16.py::test_an_unknown_ending_reports_each_requirement_in_its_own_field" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + } + ], + "round_16_runner_source": "\"\"\"Run named invented-data conformance tests with open-event auditing.\"\"\"\n\nimport hashlib\nimport json\nimport os\nfrom pathlib import Path\nimport sys\n\nCOUNTS = {\"restricted_opens\": 0, \"subprocess.Popen\": 0, \"os.system\": 0}\nBARRED = {\n \"gates.yaml\", \"adjusted_poverty.py\", \"rows.py\",\n \"ssa_trust_fund_interest_rates_2026.json\",\n \"urban2010_cola_comparison.md\", \"urban2010_fra68_comparison.md\",\n \"boomers2004_uniform_cut_comparison.md\", \"minimum_benefits_comparison.md\",\n \"m6_projection_engine.md\", \"mint8_table_user_guide.source.html\",\n \"test_anchor_provenance_erratum.py\",\n}\n\n\ndef audit(event, arguments):\n if event == \"open\" and isinstance(arguments[0], (str, bytes)):\n path = os.fsdecode(arguments[0])\n name = Path(path).name\n if (\n name in BARRED\n or name.startswith((\"adjusted_poverty.\", \"rows.\"))\n or \"/PolicyEngine/psid-data/\" in path\n or \"/microcosm-launch-evidence/\" in path\n or \"/dynasim-refs/\" in path\n or \"/claude-501/\" in path\n ):\n COUNTS[\"restricted_opens\"] += 1\n raise RuntimeError(path)\n elif event in (\"subprocess.Popen\", \"os.system\"):\n COUNTS[event] += 1\n\n\ndef main():\n for name in (\"POPULACE_DYNAMICS_PSID_DIR\", \"POPULACE_DYNAMICS_EPUF_DIR\"):\n assert os.environ[name] == \"/nonexistent/trackb-round16\"\n assert sys.argv[1:]\n assert all(\n not argument.startswith(\"tests/\") or \".py\" in argument\n for argument in sys.argv[1:]\n )\n sys.addaudithook(audit)\n from populace_dynamics.track_b import insured_status as insured\n\n source_path = Path(insured.__file__)\n original = source_path.read_bytes()\n baseline_path = os.environ.get(\"TRACKB_ROUND16_SOURCE\")\n if baseline_path:\n baseline = Path(baseline_path).read_bytes()\n exec(compile(baseline, str(source_path), \"exec\"), insured.__dict__)\n print(\"BASELINE\", hashlib.sha256(baseline).hexdigest(), flush=True)\n spec_path = os.environ.get(\"TRACKB_ROUND16_MUTATION\")\n if spec_path:\n spec = json.loads(Path(spec_path).read_text())\n assert hashlib.sha256(original).hexdigest() == spec[\"source_sha256\"]\n source = original.decode()\n for change in spec[\"changes\"]:\n assert source.count(change[\"before\"]) == 1, change[\"before\"]\n source = source.replace(change[\"before\"], change[\"after\"], 1)\n exec(compile(source, str(source_path), \"exec\"), insured.__dict__)\n print(\"MUTATION\", spec[\"name\"], flush=True)\n import pytest\n\n try:\n return pytest.main(sys.argv[1:])\n finally:\n assert source_path.read_bytes() == original\n print(\"OPEN_AUDIT\", json.dumps(COUNTS, sort_keys=True), flush=True)\n\n\nif __name__ == \"__main__\":\n raise SystemExit(main())\n", + "round_16_note": "22 of 23 mutations were killed by named public tests, and rank_ignores_status is equivalent: _settle_first_start ranks only FULLY and CURRENTLY witnesses, whose insured field is exactly count >= required, and 9,892 witnesses ranked across 600 stress declarations agreed. Ten survived a first pass. Eight were test gaps, each closed by a named test. unknown_current_treated_as_exact showed an UNKNOWN current period cannot reach _settle_first_start, so the condition left the code and the mutation left this list. Each run used nonexistent data roots, one thread per library, in-memory mutation only, unchanged implementation bytes, zero restricted opens and zero spawned-process audit events.", + "round_16_test_sha256": { + "tests/test_track_b_insured_status_fix_round_15.py": "fff894a50b7b56e1fbd3700407f50b618b0f8c45c0f430fbf4b4077ea49b1caf", + "tests/test_track_b_insured_status_fix_round_16.py": "a385b2bf2bbd85ddac8d2a912717913755aa0f12c283858a4e9c6f0e28cdfaab", + "tests/test_track_b_insured_status_status_oracle.py": "772d4dfa100d4a4be5ce07577688fc1ca6e82c0e7d573f096284401e507ba9a0", + "tests/test_track_b_insured_status_status_stress.py": "73ba47c4de99479bfb416bb82dd807d5b03a3f4529a378e4802ded2053adec7d" + }, + "round_16_replay": "Write round_16_runner_source to scratch/review/run_round16_named.py. For each round_16_mutations record, write name/source_sha256/changes to its spec_path, then execute its exact command. Mutations apply only in memory.", + "round_16_final_source_sha256": "3fed28da694474236b63ff99a1d42576994de87a81297ba6f416f4d6fdd2a25e" } diff --git a/src/populace_dynamics/track_b/insured_status.py b/src/populace_dynamics/track_b/insured_status.py index 60c9d38c9..998ec4c7a 100644 --- a/src/populace_dynamics/track_b/insured_status.py +++ b/src/populace_dynamics/track_b/insured_status.py @@ -1468,8 +1468,11 @@ def _fra_quarter(person): def _last_insured(person, credits, month, exit_month, *, years=None): last = None + # Every nonblind route needs six ordinary QCs in its own window. Below + # six, only a blind person's aggregate can still supply a historical DLI. if sum(len(fixed) + flexible for fixed, flexible in credits.values()) < 6: - return None, False + if years is None or not person.statutory_blindness: + return None, False cap = min(_qid(month), _fra_quarter(person) - 1) if person.death_date is not None: cap = min(cap, _qid(person.death_date)) @@ -1482,7 +1485,7 @@ def _last_insured(person, credits, month, exit_month, *, years=None): credited_years = [ y for y, (fixed, flex) in credits.items() if fixed or flex ] - start = max(min(credited_years) * 4, _qid(person.birth_date)) + start = max(min(credited_years, default=1937) * 4, _qid(person.birth_date)) if not person.statutory_blindness and not person.prior_disability_periods: cap = min(cap, max(credited_years) * 4 + 3 + 39) for qid in range(cap, start - 1, -1): @@ -1713,10 +1716,10 @@ def _start_sensitive_years(person, horizon): def _period_outcomes( person, completed, start, credits, month, exit_month, kinds, dated ): - """Statuses and date last insured for each ending of one start.""" + """Statuses, date last insured and witnesses for each ending.""" for option in _current_period_completions(person, completed, start, month): - statuses = tuple( - _decision_witness(option, credits, month, exit_month, kind)[0][0] + witnesses = tuple( + _decision_witness(option, credits, month, exit_month, kind) for kind in kinds ) last = ( @@ -1724,11 +1727,35 @@ def _period_outcomes( if dated else None ) - yield statuses, last + yield tuple(found[0][0] for found in witnesses), last, witnesses + + +def _witness_rank(entry): + """Order a status's witnesses the way ``_witness`` scores them.""" + witness = entry[0] + return witness[0], witness[1] - witness[2], witness[1] + + +def _witness_ranks(table): + return [[_witness_rank(entry) for entry in row] for row in table] + + +def _keep_favorable(kept, outcomes): + """Each status's best witness so far, for each period ending.""" + found = tuple(zip(*(outcome[2] for outcome in outcomes), strict=True)) + if kept is None: + return found + return tuple( + tuple( + max(entries, key=_witness_rank) + for entries in zip(*pair, strict=True) + ) + for pair in zip(kept, found, strict=True) + ) def _improves(outcome, returned, last_insured): - statuses, last = outcome + statuses, last, _ = outcome return any( found and not kept for found, kept in zip(statuses, returned, strict=True) @@ -1746,6 +1773,8 @@ def _settle_first_start( *, dated, last_insured, + reported, + favored, ): """Refuse a result no filling and its own first start can support. @@ -1758,13 +1787,24 @@ def _settle_first_start( as its own and no filling can improve on it. Flexible credits bound every filling at each possible start, so a bound that allows an improvement refuses by name. Otherwise the search begins at the filling - that insures the start, varies the latest years first, and stops at the - first filling that attains the result. A year that cannot move the - start stays flexible, so each status still places it favorably. + that insures the start and varies the latest years first until a filling + attains the result. Ties go to ``favored``, the quarters the excluded + world credits, so the returned filling keeps a year's credits where it + can. A year that cannot move the start stays flexible, so each status + still places it favorably. + + The same limit binds what a status reports. Its favorable count and + assignment can rest on a placement that would move the start, so + ``reported`` holds each status's witness for each period ending, and + the search continues past that filling until every one is attained with + the reported start or the placements run out. It returns the filling + that attained the result, with the best witnesses the reported start + allows. It returns ``(None, ())`` when any filling keeps the start, or + when ``reported`` is None because unknown facts leave only an envelope. """ # Source conflict us:oasdi-insured-one-filling-first-start if _start_fixed(person, credits, start, month, exit_month): - return + return None, () horizon = _current_period_start_horizon(person, month) for quarter in range(_qid(start), _qid(horizon) + 1): try: @@ -1799,11 +1839,16 @@ def _settle_first_start( options = { year: sorted( _assignment_candidates(*row), - key=lambda choice: not witness.issuperset(choice), + key=lambda choice: ( + len(set(choice) - witness), + len(set(choice) - favored), + choice, + ), ) for year, row in rows.items() if year in sensitive and row[1] } + joint = kept = None for index, choices in enumerate(product(*options.values())): if index == 4096: _refuse( @@ -1828,25 +1873,44 @@ def _settle_first_start( ) except InvalidFamilyInput: continue - if own_start == start and ( - returned, - last_insured, - ) in _period_outcomes( - person, - completed, - own_start, - filling, - month, - exit_month, - kinds, - dated, + if own_start != start: + continue + outcomes = tuple( + _period_outcomes( + person, + completed, + own_start, + filling, + month, + exit_month, + kinds, + dated, + ) + ) + if joint is None and any( + outcome[:2] == (returned, last_insured) for outcome in outcomes ): - return - _refuse( - InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, - "First insured start depends on annual placement " - "or prior treatment", - ) + joint = filling + if joint is not None and reported is None: + return None, () + if reported is not None: + kept = _keep_favorable(kept, outcomes) + if joint is not None and _witness_ranks(kept) == _witness_ranks( + reported + ): + return joint, kept + # Every ending must still agree once each keeps the reported start. + if joint is None or any( + entry[0][0] != insured + for entries, insured in zip(kept, returned, strict=True) + for entry in entries + ): + _refuse( + InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, + "First insured start depends on annual placement " + "or prior treatment", + ) + return joint, kept def _current_period_completions(person, completed, start, month): @@ -2370,6 +2434,43 @@ def _could_establish_current_period( return False +def _status_decision(lo_candidates, hi_candidates, envelope=None): + """One status from its candidates; ``envelope`` widens unsure counts.""" + lo, lo_quarter = lo_candidates[-1] + hi, hi_quarter = hi_candidates[0] + witnesses = [value for value, _ in (*lo_candidates, *hi_candidates)] + count_lo, count_hi, full_lo, full_hi = ( + (0, envelope, 0, envelope) + if envelope is not None + else ( + min(w[1] for w in witnesses), + max(w[1] for w in witnesses), + min(w[7] for w in witnesses), + max(w[7] for w in witnesses), + ) + ) + return _computed( + StatusDecision, + lo[0], + count_lo, + count_hi, + lo[2], + lo[3], + lo[4], + lo[5], + hi[2], + hi[3], + hi[4], + hi[5], + lo[6], + hi[6], + full_lo, + full_hi, + lo_quarter, + hi_quarter, + ) + + def _dli_cap(person, month, exit_month): cap = min(_qid(month), _fra_quarter(person) - 1) if exit_month is not None and exit_month <= month: @@ -2442,6 +2543,9 @@ def insured_status( A first successful filling cannot settle the other requested statuses: wherever placement or treatment can move the start, one filling with its own start must attain the returned result and none may beat it. + Each status then reports the best count and assignment that start + allows, and the year counts and top-level assignment describe the + returned filling. An UNKNOWN fact keeps its envelope instead. The pre1956 flag adds no route beyond the automatic alternate. A flag's own conditions remain declared facts and are not tested. History validation runs first. Uncomputable QC rows use bounded @@ -2621,7 +2725,7 @@ def insured_status( InsuredUnsupportedReason.CURRENT_PERIOD_DLI, "Current period end beyond query is unobserved", ) - decisions = {} + decisions, candidates = {}, {} for kind in ( InsuredTest.FULLY, InsuredTest.CURRENTLY, @@ -2732,36 +2836,9 @@ def insured_status( and len(_events(person, month, kind)) > 1 ) ) - witnesses = [value for value, _ in lo_candidates + hi_candidates] - count_lo, count_hi = ( - (0, maximum_qcs) - if broad - else (min(w[1] for w in witnesses), max(w[1] for w in witnesses)) - ) - full_lo, full_hi = ( - (0, maximum_qcs) - if broad - else (min(w[7] for w in witnesses), max(w[7] for w in witnesses)) - ) - decisions[kind] = _computed( - StatusDecision, - lo[0], - count_lo, - count_hi, - lo[2], - lo[3], - lo[4], - lo[5], - hi[2], - hi[3], - hi[4], - hi[5], - lo[6], - hi[6], - full_lo, - full_hi, - lo_quarter, - hi_quarter, + candidates[kind] = lo_candidates + decisions[kind] = _status_decision( + lo_candidates, hi_candidates, maximum_qcs if broad else None ) dli = None if test in (InsuredTest.ALL, InsuredTest.DISABILITY): @@ -2792,13 +2869,22 @@ def insured_status( # false current status cannot prove a positive DLI lower date. lo_date = None dli = _computed(DLIRange, lo_date, hi_date, lo_censored or hi_censored) + placement = None if lo_start is not None: + favored_rows, _ = _world( + lo_person, + upper, + _qid(month), + coverage_end_month, + True, + include_zero=True, + ) kinds = tuple( kind for kind in (InsuredTest.FULLY, InsuredTest.CURRENTLY) if decisions[kind] is not None ) - _settle_first_start( + placement, settled = _settle_first_start( person, upper, hi_start, @@ -2810,10 +2896,22 @@ def insured_status( last_insured=( dli.upper if dli is not None and not prior_unknown else None ), + reported=( + None + if unknown or prior_unknown + else tuple(candidates[kind] for kind in kinds) + ), + favored=frozenset( + quarter + for row in favored_rows.values() + for quarter in _assign_qcs(*row) + ), ) + for kind, witnesses in zip(kinds, settled, strict=False): + decisions[kind] = _status_decision(witnesses, witnesses) lo_rows, _ = _world( lo_person, - lower, + placement or lower, _qid(month), coverage_end_month, True, @@ -2838,8 +2936,8 @@ def insured_status( include_zero=True, )[0] for people, credits in ( - (lo_completions, lower), - (hi_completions, upper), + (lo_completions, placement or lower), + (hi_completions, placement or upper), ) for p in people ] diff --git a/tests/README-tiers.md b/tests/README-tiers.md index fad9d48ad..db0f21b0b 100644 --- a/tests/README-tiers.md +++ b/tests/README-tiers.md @@ -39,9 +39,9 @@ pytest --collect-only -q -m oracle_policyengine | tail -1 | Tier | Tests at HEAD | |---|---:| -| `unit` | 21,336 | +| `unit` | 21,381 | | `artifact` | 4,271 | | `integration_psid` | 1,471 | | `reproduction_legacy` | 520 | | `oracle_policyengine` | 308 | -| **Total** | **27,906** | +| **Total** | **27,951** | diff --git a/tests/test_track_b_insured_status_fix_round_15.py b/tests/test_track_b_insured_status_fix_round_15.py index 71540016d..4a8b49675 100644 --- a/tests/test_track_b_insured_status_fix_round_15.py +++ b/tests/test_track_b_insured_status_fix_round_15.py @@ -464,14 +464,15 @@ def test_a_moving_start_keeps_a_result_one_filling_attains(): @pytest.mark.parametrize( ("amount", "refused"), - ((Fraction(2950), True), (Fraction(2900), False)), + ((Fraction(2950), True), (Fraction(2900), True), (Fraction(799), False)), ) def test_blind_aggregate_decides_below_six_ordinary_qcs(amount, refused): - """The date-last-insured scan stops below six, so this site decides. + """Three first-quarter wages earn three ordinary QCs. - Three first-quarter wages earn three ordinary QCs, under the $3,000 - that would earn gift QCs. Elapsed years run 1951 through 1972, so 22 - QCs insure: $8,850 reaches 22 at $400 each, and $8,700 reaches 21. + That stays under the $3,000 that would earn gift QCs. Elapsed years run + 1951 through 1972, so 22 QCs insure at the onset, and $8,850 reaches 22 + at $400 each. $8,700 reaches 21, which meets 1972's 21 for a historical + date last insured. $2,397 reaches five, below every requirement. """ person = replace( _unestablished( diff --git a/tests/test_track_b_insured_status_fix_round_16.py b/tests/test_track_b_insured_status_fix_round_16.py new file mode 100644 index 000000000..101b2fa17 --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_16.py @@ -0,0 +1,521 @@ +"""Round 16: exact diagnostics and the aggregate below six ordinary QCs. + +Verification class: statutory conformance on invented declarations; no +population, behavioral or forecast claim. Where annual placement can move the +first insured start, each status's exact count and assignment must rest on a +filling whose own first start is the reported start (404.321(a); RS 00301.230; +source conflict us:oasdi-insured-one-filling-first-start). + +A blind person's date last insured needs no recent QCs, so fewer than six +ordinary QCs don't settle it while Act 213(c)'s aggregate could still meet the +fully insured requirement (source conflict +us:oasdi-insured-simplified-pre1951-disability-scope). +""" + +from dataclasses import replace +from datetime import date +from fractions import Fraction +from itertools import combinations, product + +import pytest +from hypothesis import example, given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as i +from populace_dynamics.track_b.gross_benefits import count_family_outcomes + +OBSERVED = i.EarningsProvenance.OBSERVED +UNKNOWN = i.EarningsProvenance.UNKNOWN +ASSIGNMENT = i.InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY +SIMPLIFIED = i.InsuredUnsupportedReason.SIMPLIFIED_PRE1951 +WEIGHT = Fraction(11, 3) +BIRTH = date(1962, 2, 2) +ONSET = date(2010, 1, 15) +QUERY = date(2011, 1, 1) +# Nineteen QCs from 2001 through 2005 leave the 2000 QC to reach 20 of 40 at +# the onset, and only 2000Q2-Q4 sit in that window. +LATER = {2000: 1, 2001: 4, 2002: 4, 2003: 4, 2004: 4, 2005: 3} +PLAIN = {1998: 4, 1999: 2, **LATER} +EARLIER = {1990: 4, 1991: 4, 1992: 4, 1993: 2, **PLAIN} +FULL_HISTORY = {1990: 4, 1991: 4} +PRIOR = i.DisabilityPeriod(date(1999, 10, 1), date(2000, 3, 31)) +BLIND_BIRTH = date(1926, 2, 2) +BLIND_QUERY = date(1974, 1, 1) +# Nineteen QCs through 1999 leave the 2000 QC to reach 20 of 40, so a first +# insured quarter of 2000Q1 holds that QC there. +TIGHT = {1995: 3, 1996: 4, 1997: 4, 1998: 4, 1999: 4, 2000: 1} +STARTED = date(2000, 1, 1) + + +def q(year, number): + return year * 4 + number - 1 + + +def _history(first, last, counts): + return { + year: ( + i.CoverageYear(OBSERVED, qc_count=counts.get(year, 0)) + if year >= 1978 + else i.CoverageYear(OBSERVED, qc_quarters=(False,) * 4) + ) + for year in range(first, last + 1) + } + + +def _established(entitlement, *priors, **changes): + values = dict( + sex=i.Sex.FEMALE, + disability_onset=ONSET, + current_disability_period_established=True, + current_disability_period_provenance=OBSERVED, + current_disability_period_end=date(2010, 12, 31), + current_disability_period_end_provenance=OBSERVED, + prior_disability_periods=priors, + prior_disability_periods_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + dib_entitlement_month=entitlement, + ) + values.update(changes) + return i.Person(BIRTH, **values) + + +def _plain(): + return _established(date(2000, 1, 1)) + + +def _tight(end, provenance=OBSERVED): + return _established( + None, + disability_onset=date(1999, 6, 15), + current_disability_period_end=end, + current_disability_period_end_provenance=provenance, + ) + + +def _with_prior(): + return _established(date(2000, 3, 1), PRIOR) + + +def _blind(**changes): + values = dict( + sex=i.Sex.FEMALE, + statutory_blindness=True, + current_disability_period_established=False, + current_disability_period_provenance=OBSERVED, + prior_disability_periods=(), + prior_disability_periods_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + values.update(changes) + return i.Person(BLIND_BIRTH, **values) + + +def _single_quarter(amount): + return i.CoverageYear( + OBSERVED, + quarterly_wages=( + Fraction(amount), + Fraction(0), + Fraction(0), + Fraction(0), + ), + ) + + +def _blind_years(amounts, last=1974): + years = _history(1937, last, {}) + for year, amount in amounts.items(): + years[year] = _single_quarter(amount) + return years + + +def _refused_row(person, years, month, reason, **options): + row = i.evaluate_insured_status( + "round-sixteen", + WEIGHT, + lambda: i.insured_status(person, years, month, **options), + ) + counts = count_family_outcomes((row,)) + assert (counts.rows, counts.weight, counts.unsupported_weight) == ( + 1, + WEIGHT, + WEIGHT, + ) + assert row.unsupported.reason is reason + return row + + +CASES = ( + pytest.param(_plain, PLAIN, id="no-prior"), + pytest.param(_with_prior, EARLIER, id="prior"), +) + + +@pytest.mark.parametrize(("person", "counts"), CASES) +@pytest.mark.parametrize("test", (i.InsuredTest.CURRENTLY, i.InsuredTest.ALL)) +@pytest.mark.parametrize( + ("exit_month", "last"), ((None, 2011), (date(2005, 12, 1), 2005)) +) +def test_count_and_assignment_keep_the_reported_start( + person, counts, test, exit_month, last +): + result = i.insured_status( + person(), + _history(1962, last, counts), + QUERY, + coverage_end_month=exit_month, + test=test, + ) + assert result.current_disability_period_start == ONSET + decision = result.currently + assert decision.insured + assert (decision.qc_count_lower, decision.qc_count_upper) == (6, 6) + assert q(2000, 1) not in decision.assigned_quarters + # The 13-quarter window can't reach a 2000 QC the start needs later. + assert ( + sum(1998 * 4 <= x < 2000 * 4 for x in decision.assigned_quarters) >= 6 + ) + + +@pytest.mark.parametrize(("person", "counts"), CASES) +def test_every_exact_diagnostic_rests_on_one_filling(person, counts): + result = i.insured_status(person(), _history(1962, 2011, counts), QUERY) + assert q(2000, 1) not in result.assigned_quarters[2000] + assert len(result.assigned_quarters[2000]) == 1 + assert q(2000, 1) not in result.fully.assigned_quarters + assert result.fully.insured and result.disability.insured + assert result.dli.upper == result.dli.lower == date(2011, 3, 31) + + +def test_a_fixed_start_keeps_the_favorable_count(): + # A twentieth later QC frees the 2000 QC to reach the 13-quarter window. + counts = {**PLAIN, 2005: 4} + result = i.insured_status(_plain(), _history(1962, 2011, counts), QUERY) + decision = result.currently + assert (decision.qc_count_lower, decision.qc_count_upper) == (7, 7) + assert q(2000, 1) in decision.assigned_quarters + + +def test_fully_only_keeps_its_status_and_count_under_a_moving_start(): + years = _history(1962, 2011, PLAIN) + result = i.insured_status(_plain(), years, QUERY, test=i.InsuredTest.FULLY) + assert result.fully.insured + assert (result.fully.qc_count_lower, result.fully.required) == (26, 26) + + +def test_a_status_only_the_moved_placement_met_refuses(): + # 1998:3 leaves five QCs in the window once the 2000 QC keeps the start. + counts = {**FULL_HISTORY, **PLAIN, 1998: 3} + _refused_row( + _plain(), + _history(1962, 2011, counts), + QUERY, + ASSIGNMENT, + test=i.InsuredTest.CURRENTLY, + ) + + +def _envelope(decision): + return ( + decision.qc_count_lower, + decision.qc_count_upper, + decision.fully_qc_count_lower, + decision.fully_qc_count_upper, + ) + + +@pytest.mark.parametrize( + ("test", "name"), + ((i.InsuredTest.FULLY, "fully"), (i.InsuredTest.CURRENTLY, "currently")), +) +def test_unknown_years_keep_the_universal_envelope(test, name): + # 1995 sits outside every window that fixes the start, so the 2000 QC + # still moves it, and UNKNOWN earnings leave only the outer bound. + years = _history(1962, 2011, PLAIN) + years[1995] = i.CoverageYear(UNKNOWN) + result = i.insured_status(_plain(), years, QUERY, test=test) + assert result.unknown_years == (1995,) + assert _envelope(getattr(result, name)) == (0, 30, 0, 30) + + +def test_unknown_priors_keep_the_universal_envelope(): + person = replace( + _plain(), + prior_disability_periods=(), + prior_disability_periods_provenance=UNKNOWN, + ) + result = i.insured_status( + person, + _history(1962, 2011, PLAIN), + QUERY, + test=i.InsuredTest.CURRENTLY, + ) + assert _envelope(result.currently) == (0, 26, 0, 26) + + +def test_an_unknown_ending_keeps_each_endings_witness(): + person = replace( + _plain(), + current_disability_period_end=None, + current_disability_period_end_provenance=UNKNOWN, + ) + result = i.insured_status( + person, + _history(1962, 2011, PLAIN), + QUERY, + test=i.InsuredTest.CURRENTLY, + ) + decision = result.currently + assert decision.insured + assert (decision.qc_count_lower, decision.qc_count_upper) == (6, 6) + assert q(2000, 1) not in decision.assigned_quarters + + +def test_an_unknown_ending_reports_each_requirement_in_its_own_field(): + # A later ending excludes more elapsed years, so the last ending sets + # the lower requirement and the first sets the upper. + person = replace( + _established( + None, + disability_onset=date(1992, 1, 15), + current_disability_period_end=None, + current_disability_period_end_provenance=UNKNOWN, + ), + birth_date=date(1956, 2, 2), + ) + counts = { + 1978: 2, + 1987: 2, + 1988: 4, + 1989: 3, + 1990: 4, + 1991: 4, + 1992: 2, + 1994: 1, + } + decision = i.insured_status( + person, + _history(1956, 1998, counts), + date(1998, 7, 1), + test=i.InsuredTest.FULLY, + ).fully + assert (decision.required, decision.upper_required) == (16, 19) + + +@pytest.mark.parametrize( + ("end", "count"), + ( + (date(2000, 6, 30), 6), + (date(2000, 9, 30), 7), + (date(2001, 12, 31), 8), + ), +) +def test_a_later_ending_meets_currently_at_the_reported_start(end, count): + result = i.insured_status( + _tight(end), + _history(1962, 2003, {**TIGHT, 2001: 4, 2002: 1}), + date(2003, 4, 1), + test=i.InsuredTest.CURRENTLY, + ) + decision = result.currently + assert result.current_disability_period_start == STARTED + assert result.assigned_quarters[2000] == (q(2000, 1),) + assert decision.insured + assert (decision.qc_count_lower, decision.qc_count_upper) == (count, count) + + +@pytest.mark.parametrize( + ("end", "provenance"), + ((date(2000, 3, 31), OBSERVED), (None, UNKNOWN)), + ids=("first-quarter-ending", "unknown-ending"), +) +def test_an_ending_the_reported_start_fails_refuses(end, provenance): + # Ending in 2000Q1 windows 2000Q2-2003Q2. The 2000 QC reaches six there + # only outside 2000Q1, which moves the start. An unknown ending includes + # that one, so its later endings can't carry the status. + _refused_row( + _tight(end, provenance), + _history(1962, 2003, {**TIGHT, 2001: 4, 2002: 1}), + date(2003, 4, 1), + ASSIGNMENT, + test=i.InsuredTest.CURRENTLY, + ) + + +@pytest.mark.parametrize("test", (i.InsuredTest.DISABILITY, i.InsuredTest.ALL)) +def test_a_date_only_a_moved_placement_reaches_refuses(test): + # Nineteen QCs from 2001 through 2005 need the 2000 QC for 20 of 40 after + # 2009, and the latest date needs it in 2000Q2 or later. + counts = {**TIGHT, 2001: 4, 2002: 4, 2003: 4, 2004: 4, 2005: 3} + _refused_row( + _tight(date(2000, 3, 31)), + _history(1962, 2012, counts), + date(2012, 1, 1), + ASSIGNMENT, + test=test, + ) + + +def test_a_date_the_reported_start_reaches_computes(): + counts = {**TIGHT, 2001: 4, 2002: 4, 2003: 4, 2004: 4, 2005: 4} + result = i.insured_status( + _tight(date(2000, 3, 31)), + _history(1962, 2012, counts), + date(2012, 1, 1), + ) + assert result.current_disability_period_start == STARTED + assert result.dli.lower == result.dli.upper == date(2010, 12, 31) + + +def _lawful_currently(counts): + """Exhaust placements in plain arithmetic for the no-prior record. + + FULL_HISTORY's eight QCs sit outside both windows and meet fully at 26. + """ + options = [ + combinations(range(year * 4, year * 4 + 4), count) + for year, count in sorted(counts.items()) + ] + window = range(q(2000, 1) - 12, q(2000, 1) + 1) + onset_window = range(q(2010, 1) - 39, q(2010, 1) + 1) + best = None + for pieces in product(*options): + credits = {credit for piece in pieces for credit in piece} + if len(credits) + 8 < 26: + continue + if sum(credit in onset_window for credit in credits) < 20: + continue + held = sum(credit in window for credit in credits) + best = held if best is None else max(best, held) + return best + + +@settings(max_examples=40, deadline=None) +@example(early=4, middle=2, later=4, last=3) +@example(early=4, middle=2, later=4, last=4) +@example(early=2, middle=3, later=2, last=3) +@given( + early=st.integers(1, 4), + middle=st.integers(1, 3), + later=st.integers(1, 4), + last=st.integers(2, 4), +) +def test_a_computed_count_is_the_best_lawful_count(early, middle, later, last): + counts = { + 1998: early, + 1999: middle, + 2000: 1, + 2001: later, + 2002: 4, + 2003: 4, + 2004: 4, + 2005: last, + } + expected = _lawful_currently(counts) + try: + result = i.insured_status( + _plain(), + _history(1962, 2011, {**FULL_HISTORY, **counts}), + QUERY, + test=i.InsuredTest.CURRENTLY, + ) + except i.InsuredConfigurationUnsupported: + return + except i.InvalidFamilyInput: + assert expected is None + return + if result.current_disability_period_start == ONSET: + assert result.currently.qc_count_upper == expected + + +@pytest.mark.parametrize("test", (i.InsuredTest.DISABILITY, i.InsuredTest.ALL)) +@pytest.mark.parametrize( + ("exit_month", "last"), + ( + (None, 1974), + (date(1974, 1, 1), 1974), + (date(1950, 12, 1), 1950), + ), +) +def test_aggregate_below_six_ordinary_qcs_refuses_the_dli( + test, exit_month, last +): + # Three ordinary QCs, and $8,800 / $400 = 22 against the 22 of 1973. + years = _blind_years({1948: 2933, 1949: 2933, 1950: 2934}, last) + _refused_row( + _blind(), + years, + BLIND_QUERY, + SIMPLIFIED, + test=test, + coverage_end_month=exit_month, + ) + + +def test_aggregate_with_no_ordinary_qc_refuses_the_dli(): + # $49 in each quarter earns no QC, and 52 quarters total $2,548. + years = _history(1937, 1974, {}) + for year in range(1938, 1951): + years[year] = i.CoverageYear( + OBSERVED, quarterly_wages=(Fraction(49),) * 4 + ) + _refused_row( + _blind(), + years, + BLIND_QUERY, + SIMPLIFIED, + test=i.InsuredTest.DISABILITY, + ) + + +@pytest.mark.parametrize("blind", (False, True)) +def test_no_wages_leave_no_dli(blind): + result = i.insured_status( + _blind(statutory_blindness=blind), + _history(1937, 1974, {}), + BLIND_QUERY, + test=i.InsuredTest.DISABILITY, + ) + assert not result.disability.insured + assert result.dli.upper is None + + +def test_a_nonblind_record_below_six_needs_no_aggregate_refusal(): + # No recent rule can pass on three ordinary QCs, whatever the aggregate. + years = _blind_years({1948: 2933, 1949: 2933, 1950: 2934}) + result = i.insured_status( + _blind(statutory_blindness=False), + years, + BLIND_QUERY, + test=i.InsuredTest.DISABILITY, + ) + assert not result.disability.insured + assert result.dli.upper is None + + +@settings(max_examples=40, deadline=None) +@example(total=2399) +@example(total=2400) +@given(total=st.integers(150, 9000)) +def test_the_dli_refusal_tracks_six_aggregate_qcs(total): + # Six aggregate QCs meet the 404.110 floor at the earliest credited + # quarter, so the refusal needs only the $2,400 total. + share = total // 3 + amounts = {1948: share, 1949: share, 1950: total - 2 * share} + years = _blind_years(amounts) + + def call(): + return i.insured_status( + _blind(), years, BLIND_QUERY, test=i.InsuredTest.DISABILITY + ) + + if total // 400 >= 6: + with pytest.raises(i.InsuredConfigurationUnsupported) as error: + call() + assert error.value.reason is SIMPLIFIED + else: + result = call() + assert not result.disability.insured + assert result.dli.upper is None diff --git a/tests/test_track_b_insured_status_status_oracle.py b/tests/test_track_b_insured_status_status_oracle.py index bc230986b..44bb43b0d 100644 --- a/tests/test_track_b_insured_status_status_oracle.py +++ b/tests/test_track_b_insured_status_status_oracle.py @@ -21,7 +21,9 @@ insured start; that start supplies the current period for FULLY and CURRENTLY. DISABILITY must qualify without using the period it establishes. Each returned status must equal the favorable Boolean over all lawful -fillings. A named refusal retains the declaration and passes the oracle. +fillings. Each exact count, assignment and date last insured must be the best +a filling with the reported first start attains. A named refusal retains the +declaration and passes the oracle. """ from dataclasses import dataclass @@ -139,6 +141,7 @@ def favorable_statuses(case): answer = [False, False, False] lawful = 0 starts = set() + own = {} onset = date(2000, 2, 15) ending = date(2002, 12, 31) at = quarter(case.month) @@ -173,12 +176,36 @@ def favorable_statuses(case): onset if first == quarter(onset) else date(year, 3 * q + 1, 1) ) completed = case.periods + ((start, ending),) + best = own.setdefault( + first, + {"fully": (False, -99, -1), "currently": (False, -99, -1)}, + ) + best.setdefault("fillings", []).append(credits) for status_periods in (completed, ()): usable = _usable(credits, at, status_periods) - answer[0] |= len(usable) >= _fully_requirement( - at, status_periods + needed = _fully_requirement(at, status_periods) + held = _recent(usable, at, status_periods, 13) + answer[0] |= len(usable) >= needed + answer[1] |= held >= 6 + best["fully"] = max( + best["fully"], + (len(usable) >= needed, len(usable) - needed, len(usable)), + ) + best["currently"] = max( + best["currently"], (held >= 6, held - 6, held) + ) + best["last"] = max( + ( + best.get("last", -1), + *( + q + for q in range(min(credits), at + 1) + if _disability( + credits, q, status_periods, case.blind + ) + ), + ) ) - answer[1] |= _recent(usable, at, status_periods, 13) >= 6 # The first insured start is itself a valid 404.131 witness. # Later queries do not erase that witness, and the current # period is never used to establish its own DISABILITY status. @@ -186,11 +213,31 @@ def favorable_statuses(case): _disability(credits, q, establishment_periods, case.blind) for q in range(quarter(onset), at + 1) ) - return tuple(answer), lawful, tuple(sorted(starts)) + return tuple(answer), lawful, tuple(sorted(starts)), own + + +def _check_diagnostics(case, result, best): + """Every exact diagnostic must belong to the reported start.""" + for name in ("fully", "currently"): + decision = getattr(result, name) + count = decision.qc_count_upper + assert decision.qc_count_lower == count, (case, name, result) + assert ( + decision.insured, + count - decision.required, + count, + ) == best[ + name + ], (case, name, best[name], result) + assert any( + set(decision.assigned_quarters) <= credits + for credits in best["fillings"] + ), (case, name, decision) + assert quarter(result.dli.upper) == best["last"], (case, result) def _check(case): - expected, lawful, starts = favorable_statuses(case) + expected, lawful, starts, own = favorable_statuses(case) observed = rule.EarningsProvenance.OBSERVED person = rule.Person( date(1960, 2, 2), @@ -230,12 +277,15 @@ def _check(case): for name in ("fully", "currently", "disability") ) assert actual == expected, (case, actual, expected, starts, result) + _check_diagnostics( + case, result, own[quarter(result.current_disability_period_start)] + ) return "computed" def test_status_oracle_review_completion_has_favorable_fully_status(): case = Declaration() - expected, lawful, starts = favorable_statuses(case) + expected, lawful, starts, _ = favorable_statuses(case) assert lawful and 2000 * 4 + 1 in starts assert expected[0] _check(case) diff --git a/tests/test_track_b_insured_status_status_stress.py b/tests/test_track_b_insured_status_status_stress.py index 486bb4a05..b9be2773f 100644 --- a/tests/test_track_b_insured_status_status_stress.py +++ b/tests/test_track_b_insured_status_status_stress.py @@ -10,16 +10,19 @@ four partial years, no prior, a clear prior or an overlapping prior, and blindness in a quarter of cases all vary by seed. A second generator adds a DIB entitlement month, which ends a CURRENTLY window before the onset. A third -draws ages 22-30 at onset, where 404.130(c) and (d) apply. Declared priors are -not re-adjudicated. No flags, UNKNOWN facts, DLI, subsequent-special routes, -raw earnings or death are claimed. +draws ages 22-30 at onset, where 404.130(c) applies. A fourth declares a +special-insured prior after age 31, where 404.130(d) applies. Declared priors +are not re-adjudicated. No flags, UNKNOWN facts, raw earnings or death are +claimed. Every annual placement and both all-prior treatments are enumerated. A lawful filling has its own first insured start (404.321(a)), and that start supplies -the current period for FULLY and CURRENTLY. Each returned status must equal -the favorable Boolean over lawful fillings (RS 00301.230), and a true status -must hold on a filling whose first start is the reported start. A rejection -needs no lawful filling. A named refusal retains the declaration and passes. +the current period for FULLY, CURRENTLY and the date last insured. Each +returned status must equal the favorable Boolean over lawful fillings +(RS 00301.230), and a true status must hold on a filling whose first start is +the reported start. Each exact count, assignment and date last insured must +also be the best a filling with that start attains. A rejection needs no +lawful filling. A named refusal retains the declaration and passes. """ import calendar @@ -93,10 +96,12 @@ def recent(use, at, periods, length): return count -def under_31(birth, use, at, periods): +def under_31(birth, use, at, periods, special=False): """404.130(c), (d): half the quarters after age 21, or 6 of 12.""" attained_21 = quarter(date(birth.year + 21, birth.month, birth.day)) - if at >= quarter(date(birth.year + 31, birth.month, birth.day)): + if not special and at >= quarter( + date(birth.year + 31, birth.month, birth.day) + ): return False elapsed = [ candidate @@ -112,13 +117,25 @@ def under_31(birth, use, at, periods): return credited >= max(6, min(len(elapsed), 40) // 2) -def disability(birth, credits, at, periods, blind): +def disability(birth, credits, at, periods, blind, special=False): use = usable(credits, at, periods) fully = len(use) >= requirement(birth, at // 4, periods) return fully and ( blind or recent(use, at, periods, 40) >= 20 - or under_31(birth, use, at, periods) + or under_31(birth, use, at, periods, special) + ) + + +def last_insured(birth, credits, at, periods, blind, special): + """Latest quarter through the query that insures a potential onset.""" + return max( + ( + candidate + for candidate in range(min(credits, default=at), at + 1) + if disability(birth, credits, candidate, periods, blind, special) + ), + default=None, ) @@ -134,7 +151,9 @@ def placements(annual): def lawful_fillings(case): """Exhaust every filling before comparing to a public result. - Each lawful filling gives its first start and three statuses. + Each lawful filling gives its first start, three statuses, the best + (insured, margin, count) for FULLY and CURRENTLY, its date last insured + quarter and its credits. """ birth, onset, ending, month = ( case["birth"], @@ -143,6 +162,7 @@ def lawful_fillings(case): case["month"], ) blind, prior, annual = case["blind"], case["prior"], case["annual"] + special = case.get("special", False) at = quarter(month) events = [ event for event in (case.get("entitlement"),) if event is not None @@ -155,7 +175,9 @@ def lawful_fillings(case): ( candidate for candidate in range(quarter(onset), quarter(ending) + 1) - if disability(birth, credits, candidate, used, blind) + if disability( + birth, credits, candidate, used, blind, special + ) ), None, ) @@ -167,29 +189,52 @@ def lawful_fillings(case): start = ( onset if first == quarter(onset) else date(year, 3 * q + 1, 1) ) - fully = currently = False + fully_best = currently_best = (False, -99, -1) + latest = None for periods in (prior + ((start, ending),), ()): use = usable(credits, at, periods) - fully |= len(use) >= requirement(birth, month.year, periods) - currently |= any( - recent( + needed = requirement(birth, month.year, periods) + fully_best = max( + fully_best, + (len(use) >= needed, len(use) - needed, len(use)), + ) + for event in events: + held = recent( usable(credits, quarter(event), periods), quarter(event), periods, 13, ) - >= 6 - for event in events + currently_best = max( + currently_best, (held >= 6, held - 6, held) + ) + latest = max( + filter( + None, + ( + latest, + last_insured( + birth, credits, at, periods, blind, special + ), + ), + ), + default=None, ) found.append( ( first, - fully, - currently, + fully_best[0], + currently_best[0], any( - disability(birth, credits, candidate, used, blind) + disability( + birth, credits, candidate, used, blind, special + ) for candidate in range(quarter(onset), at + 1) ), + fully_best, + currently_best, + latest, + credits, ) ) return found @@ -207,7 +252,10 @@ def public(case): current_disability_period_end=case["ending"], current_disability_period_end_provenance=observed, prior_disability_periods=tuple( - rule.DisabilityPeriod(a, b) for a, b in case["prior"] + rule.DisabilityPeriod( + a, b, special_insured=case.get("special", False) + ) + for a, b in case["prior"] ), prior_disability_periods_provenance=observed, sspa211_applies=False, @@ -341,6 +389,59 @@ def under_31_declaration(seed): } +def subsequent_declaration(seed): + """Declare a special-insured prior before 31, and an onset after it. + + The special prior opens 404.130(d) at the later onset. + """ + case = declaration(seed) + draw = random.Random(f"subsequent-{seed}") + onset = case["onset"] + birth = date(onset.year - draw.randint(32, 40), 2, 2) + begins = date(birth.year + draw.randint(24, 30), 7, 1) + ends = date(begins.year + draw.randint(0, 1), 12, 31) + case.update(birth=birth, prior=((begins, ends),), special=True) + return case + + +def check_diagnostics(case, result, fillings): + """Every exact diagnostic must belong to the reported start.""" + start = quarter(result.current_disability_period_start) + own = [filling for filling in fillings if filling[0] == start] + for name, position in (("fully", 4), ("currently", 5)): + decision = getattr(result, name) + count = decision.qc_count_upper + score = (decision.insured, count - decision.required, count) + assert decision.qc_count_lower == count, (case, name, result) + assert score == max(filling[position] for filling in own), ( + case, + name, + score, + result, + ) + assert any( + filling[position] == score + and set(decision.assigned_quarters) <= filling[7] + for filling in own + ), (case, name, decision) + assigned = { + credit + for quarters in result.assigned_quarters.values() + for credit in quarters + } + assert any(assigned <= filling[7] for filling in own), (case, assigned) + for year, quarters in result.assigned_quarters.items(): + assert result.qcs_by_year[year] == (len(quarters), len(quarters)), ( + case, + year, + result, + ) + upper = result.dli.upper + assert (None if upper is None else quarter(upper)) == max( + filling[6] for filling in own + ), (case, upper, own) + + def check(case): fillings = lawful_fillings(case) try: @@ -364,9 +465,36 @@ def check(case): assert not insured or any( filling[0] == start and filling[index] for filling in fillings ), (case, actual, start, fillings) + check_diagnostics(case, result, fillings) return "computed" +@pytest.mark.parametrize("seed", (5000026, 5000168)) +def test_status_stress_year_counts_follow_the_returned_filling(seed): + # The start's witness leaves a prior's interior holding a year's QCs. + assert check(declaration(seed)) == "computed" + + +@pytest.mark.parametrize("seed", (5000005, 5000019)) +def test_status_stress_candidate_order_changes_nothing(seed, monkeypatch): + forward = public(declaration(seed)) + candidates = rule._assignment_candidates + monkeypatch.setattr( + rule, + "_assignment_candidates", + lambda *row: tuple(reversed(tuple(candidates(*row)))), + ) + backward = public(declaration(seed)) + assert dict(backward.assigned_quarters) == dict(forward.assigned_quarters) + assert dict(backward.qcs_by_year) == dict(forward.qcs_by_year) + + +def test_status_stress_returned_filling_keeps_credited_endpoints(): + # 2016 holds three QCs inside a current period, and its two endpoints + # credit two of them wherever the third falls. + assert public(declaration(5000133)).qcs_by_year[2016] == (2, 2) + + @pytest.mark.parametrize("seed", SPLIT_SEEDS) def test_status_stress_refuses_a_start_no_filling_supports(seed): with pytest.raises(rule.InsuredConfigurationUnsupported) as error: @@ -395,3 +523,9 @@ def test_status_stress_with_an_entitlement_month(seed): @given(seed=st.integers(0, 2**32 - 1)) def test_status_stress_under_31(seed): check(under_31_declaration(seed)) + + +@settings(max_examples=120, deadline=None, derandomize=True) +@given(seed=st.integers(0, 2**32 - 1)) +def test_status_stress_subsequent_special(seed): + check(subsequent_declaration(seed)) diff --git a/tests/tier_counts.json b/tests/tier_counts.json index 3961eebd6..a7de63c4f 100644 --- a/tests/tier_counts.json +++ b/tests/tier_counts.json @@ -1,7 +1,7 @@ { "schema_version": 1, "counts": { - "unit": 21336, + "unit": 21381, "artifact": 4271, "integration_psid": 1471, "reproduction_legacy": 520, From ab1692b448df1516b58e0def05dfe782a5401167 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sun, 1 Nov 2026 14:42:04 -0500 Subject: [PATCH 23/46] Track B insured status: refuse where the long period's readings differ Sol's twelfth review of e9f4140c found two mediums, and both reproduced. - Past 40 counted quarters a subsequent-special period has two readings. Clause (iii) of Act 223(c)(1)(B) asks for half the whole period, and 404.130(d)(2) asks for 20 of the last 40, which adds nothing to 404.130(b). The rule took the capped reading without logging it, and it lost the date last insured for a record the Act's reading insures. The rule now computes only where the readings agree, and refuses with subsequent_special_long_period_unsupported otherwise. The session rejected a third parse, 20 QCs anywhere in the period, because it drops "out of 40 calendar quarters" and refuses RS 00301.147's Mary Brown. The session logged the reading as us:oasdi-insured-subsequent-special-long-period, and the refusal stands until d1920 rules the pattern. - The lower date on an UNKNOWN ending kept each ending's favorable placement. _settle_lower_date now searches fillings that keep the reported start, and refuses by name unless each ending reaches the lower date. A mutation found that UNKNOWN priors skipped the new check, because they list no endings. The search now reads the completion with only the listed periods, which holds every ending. _unknown_prior_joint_shortfall takes the Act's whole period, because it proves impossibility, and its own 40-quarter test carries the capped reading. No gate, loop, step or run artifact changes. Invariants: a long subsequent-special period computes exactly where both readings agree and otherwise refuses by name with its row and weight; no reading's conflict becomes an input error; every period ending reaches the reported lower date on a filling with the reported start; UNKNOWN priors reach the same check. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 152 +++- .../track_b_insured_status_mutations.json | 497 ++++++++++++- .../track_b_insured_status_rulespec_issue.md | 6 + .../track_b/insured_status.py | 229 ++++-- ..._b_insured_status_classification_oracle.py | 36 +- ...est_track_b_insured_status_fix_round_17.py | 666 ++++++++++++++++++ ...st_track_b_insured_status_status_stress.py | 203 +++++- 7 files changed, 1684 insertions(+), 105 deletions(-) create mode 100644 tests/test_track_b_insured_status_fix_round_17.py diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index 888dd5eeb..140453938 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -670,7 +670,8 @@ input. An input error propagates and creates no row. | Pre1951 self-employment income | `pre1951_self_employment_unsupported` | | Earnings require an increment after 2027 | `qc_amount_year_unsupported` | | Query before 1968; blind query before 1973; subsequent-special query before May 1983 | `entitlement_before_1968_unsupported`, `blindness_before_1973_unsupported`, `subsequent_special_before_1983_unsupported` | -| More than 4,096 disability-boundary combinations, unresolved ordinary-establishment overlap requiring more than 4,096 credit fillings, or a first start that placement or prior treatment can move with no one filling supporting the returned result, after fixed overlap and every credit-count proof applicable to the surviving flag classes and foreign-credit declaration | `disability_boundary_assignments_unsupported` | +| A subsequent-special period past 40 counted quarters where half the whole period and 20 of the last 40 give different results | `subsequent_special_long_period_unsupported` | +| More than 4,096 disability-boundary combinations, unresolved ordinary-establishment overlap requiring more than 4,096 credit fillings, a first start that placement or prior treatment can move with no one filling supporting the returned result, or a lower date some ending can't reach on a filling with the reported start, after fixed overlap and every credit-count proof applicable to the surviving flag classes and foreign-credit declaration | `disability_boundary_assignments_unsupported` | The round-3 observable-trigger audit covers every `CoverageCondition`. An explicit condition continues to refuse under its own reason when the @@ -849,14 +850,14 @@ to a statutory sentence that does not state it. | B7. DLI lies through query without frozen exit, or through the pre-FRA-quarter/death horizon with frozen coverage; `None` is the bottom bound. A future exit cannot remove query censoring. | RS .148 defines DLI as "the last day in the last quarter" in which status is met and limits the search relative to FRA. B404.146(b) caps credits after death; A216(i)(2)(B) caps new periods. Future undeclared work is not assumed zero. Specialist routes are refused before this ordinary DLI calculation. | | B8. For a nonblind ordinary worker with no prior period, no DLI can lie more than 39 quarters after the last credited quarter. | B404.130(b)(2) requires "at least 20 QCs in the 40-quarter period ... ending with that quarter". After 39 later quarters no original QC remains. Blindness and prior-period special/exclusion routes disable this search shortcut; flagged or observable specialist routes refuse. | | B9. With unknown periods the disregard DLI is a lower bound and the permitted query/FRA/death horizon is the upper bound; unknown SSPA applicability reduces any positive DLI lower bound to `None`. | C320(a) permits favorable disregard; B404.130(f) permits counting all prior-period quarters; RS .102 B.2 imposes an additional requirement. The bound does not infer a particular recovery or history. Exemption can recover the ordinary upper witness but cannot exceed the calendar horizon. | -| B10. UNKNOWN-ending DLI bounds include every end candidate. With an unresolved ongoing end, known prior history, and frozen-exit future horizon beyond query, the named DLI-horizon refusal remains. | C321(c)'s alternative endings and RS .148's last qualifying quarter permit different historical DLI witnesses. The candidate extrema bound all declared endings; no recovery beyond the query is inferred. Refusal covers the unobserved future administrative fact. | +| B10. UNKNOWN-ending DLI bounds include every end candidate. With an unresolved ongoing end, known prior history, and frozen-exit future horizon beyond query, the named DLI-horizon refusal remains. | C321(c)'s alternative endings and RS .148's last qualifying quarter permit different historical DLI witnesses. The candidate extrema bound all declared endings; no recovery beyond the query is inferred. Refusal covers the unobserved future administrative fact. Round 17 requires every ending to reach the lower date on a filling with the reported start, and refuses by name otherwise. | | B11. At most 4,096 combinations of disability endpoint assignments are searched exactly, after any applicable impossibility proof. | B404.143(b) and RS .230 permit favorable assignment; B404.130(f) makes credited endpoints decisive. Fixed-overlap, six-QC, and I15's minimum-requirement checks precede `_boundary_variants`, including both alternate-path calls and UNKNOWN-prior-history feasibility. A remaining excess returns `disability_boundary_assignments_unsupported`; computational complexity is neither a statutory impossibility bound nor permission to retain an all-invalid declaration. | -| B12. Ordinary counted windows have 13 quarters for current insurance and 40 for ordinary disability; young/subsequent special windows require half their elapsed quarters after dropping an odd remainder, with a six-QC minimum and 20/40 ceiling. | B404.120(a) says "13-quarter period"; .130(b) says "20 QCs in the 40-quarter period"; .130(c)-(d) and A216(i)(3)(B) supply the half-quarter, odd-remainder, and 6/12 alternatives. Blindness uses only the fully insured prerequisite. A fully-route flag must still leave a recent-rule witness or possible automatic pre1956 alternate where I16 applies; the pre1956 flag adds no route beyond that alternate. Specialist paths retaining possibility receive their named refusal. | +| B12. Ordinary counted windows have 13 quarters for current insurance and 40 for ordinary disability; young/subsequent special windows require half their elapsed quarters after dropping an odd remainder, with a six-QC minimum. The young-worker window holds at most 39 quarters. A subsequent-special period past 40 quarters computes only where the Act's whole period and 404.130(d)(2)'s 20 of 40 agree (round 17). | B404.120(a) says "13-quarter period"; .130(b) says "20 QCs in the 40-quarter period"; .130(c)-(d) and A216(i)(3)(B) supply the half-quarter, odd-remainder, and 6/12 alternatives. Blindness uses only the fully insured prerequisite. A fully-route flag must still leave a recent-rule witness or possible automatic pre1956 alternate where I16 applies; the pre1956 flag adds no route beyond that alternate. Specialist paths retaining possibility receive their named refusal. | | B13. Indexed annual QC amounts are at least the prior year's statutory increment and the rounded indexed 1978 amount, with nearest-$10 rounding and $5 ties upward. | A213(d)(2) chooses "the larger of" the prior increment and indexed amount, rounded to "the next higher multiple of $10" at a $5 tie. This exact parameter calculation has no disability or specialist alternative; input-domain checks require positive NAWI and a statutory prior increment. | | B14. Declaring continuity never widens the administrative-end candidate set; every returned status and count envelope remains valid for every retained concrete ending. | C321(c)'s ending events still govern. Set intersection with ends on/after the observation can only remove candidates; it creates neither an ending nor a new credit. The universal envelope remains unchanged where other unknown facts require it. | | B15. Ordinary establishment overlap resolution enumerates at most 4,096 unknown-credit fillings after its fixed-date monotonicity, candidate-quarter, six-QC, and minimum-requirement proofs. | C320(b)(2) and C321(a) require one insured beginning consistent with the complete declaration. I13 settles fixed-quarter overlap and I15 settles a known-history nonblind lifetime-QC shortfall before enumeration. If neither settles the declaration, a search beyond the limit returns `disability_boundary_assignments_unsupported`; it asserts neither a concrete filling nor an input error. | | B16. A deferred raw-conversion row retains independently computable ordinary credits in its minimum and every enumerated filling, and cannot exceed feasible calendar-quarter credits in its maximum. | A213(d)(2)'s prior-increment floor bounds future annual credits above by the captured 2027 increment applied to the supplied wages plus SE income; the possibility-only lower bound is zero. Raw 1937 allocation remains zero through four because A213(b)'s half-year rule is unresolved. For separate pre1955 agriculture or pre1951 SE, supported quarterly wage credits and supported post1950 calendar-year SE credits remain fixed; unresolved additional allocation can fill only remaining allowed quarters. Both minimum and maximum fillings may violate derived overlap even when a middle filling is valid, so neither endpoint alone proves impossibility. These bounds do not adjudicate a specialist allocation or replace its refusal. | -| B17. The first-start check refuses when flexible credits allow a better result at any possible start, and it searches at most 4,096 placements of the annual years that can change a first insured quarter. | 404.321(a) gives a record one start, and RS .230 makes placement flexible. A year wholly inside every tested window and untouched by a period adds its full count wherever its QCs fall, so it stays flexible. Without prior periods, an insured worst filling proves no filling starts later, and the check stops. The bound can refuse a declaration that no concrete filling improves, and a search can reach its limit before it attains a result. Round 16's longer search for each status's witness can reach the same limit. All return `disability_boundary_assignments_unsupported`, so the row keeps its weight; none asserts a filling or an input error. | +| B17. The first-start check refuses when flexible credits allow a better result at any possible start, and it searches at most 4,096 placements of the annual years that can change a first insured quarter. | 404.321(a) gives a record one start, and RS .230 makes placement flexible. A year wholly inside every tested window and untouched by a period adds its full count wherever its QCs fall, so it stays flexible. Without prior periods, an insured worst filling proves no filling starts later, and the check stops. The bound can refuse a declaration that no concrete filling improves, and a search can reach its limit before it attains a result. Round 16's longer search for each status's witness and round 17's lower-date search can reach the same limit. All return `disability_boundary_assignments_unsupported`, so the row keeps its weight; none asserts a filling or an input error. | The round-5 adversarial audit revisits each row in both directions in `scratch/review/round5-premise-audit.md`: a valid filling cannot be rejected, @@ -2146,6 +2147,149 @@ The invariants added in this round are executed by these tests: `test_aggregate_below_six_ordinary_qcs_refuses_the_dli`, `test_aggregate_with_no_ordinary_qc_refuses_the_dli`). +## Round 17 the long subsequent-special period and the lower date + +Verification class: statutory conformance on invented declarations only. +This correction admits no population, behavioral, payment, or forecast claim. +Sol's twelfth review of `e9f4140c` raised two mediums, and both reproduced. + +### The cap on a long subsequent-special period + +Clause (iii) of Act 223(c)(1)(B) and 216(i)(3)(B) asks for "not less than +one-half of the quarters beginning after such individual attained age 21", +with no cap. 404.130(d)(2) asks for one-half of the same period "up to a +maximum of 20 QCs out of 40 calendar quarters", and RS 00301.147 B.2.a repeats +those words. RS 00301.147's three examples stop at 33 quarters, so no capture +shows SSA applying the cap. Past 40 counted quarters the sources give two +readings: + +- half the whole period, as the Act says; +- 20 of the last 40 counted quarters, as 404.130(d)(2) says. Those are the + quarters of 404.130(b), so this reading adds nothing to that rule. + +A third parse takes 20 QCs anywhere in the period. The session rejected it. It +drops "out of 40 calendar quarters", and every period in 404.130 ends with the +tested quarter, so the test would stop asking about recent work. It would also +refuse RS 00301.147's Mary Brown, whose status the manual prints. Counting the +prior's quarters under 404.130(f) leaves 20 QCs in 48 quarters at 1983Q2, and +that parse alone would move the date last insured past 1983-03-31. + +Through round 16 the rule took the capped reading without logging it, and the +stress oracle repeated it. An invented woman born 1960-02-02 has a special +prior from 1983-01-15 through 1983-06-30, annual QCs 1981:3, 1982:3, four in +each of 1984 to 1986 and 1987:2, and onset 1991-10-15. The period holds 41 +counted quarters, so the test needs 20, and all 20 QCs sit in it. Its last 40 +quarters hold 19. At `e9f4140c` DISABILITY computed false with a date last +insured of 1991-09-30, where the Act's reading insures this record through +1991-12-31. +With an established period the same record raised `InvalidFamilyInput`, even +for an age-62 FULLY request. + +The rule now computes only where the two readings agree. `_witness` refuses +with `subsequent_special_long_period_unsupported` when no candidate insures and +the whole period holds at least half its quarters after dropping an odd +remainder. The refusal needs no fully insured test: across 166,080 combinations +of birth, prior and query date, half a long period exceeded the requirement by +at least 10 QCs, and `test_half_a_long_period_clears_the_fully_insured_count` +holds that. At 40 counted quarters or fewer the readings match. A FULLY +request with no established period reads no disability test, so it still +computes. The refusal reaches a date last insured that the 40-quarter rule +ends before the Act's reading would, because the date scan calls the same +witness. It also reaches +the period that 404.130(f) counts in full, where the prior's quarters take a +period past 40. `_unknown_prior_joint_shortfall` proves impossibility, so its +`special_recent` takes the Act's whole period, and its own 40-quarter test +carries the capped reading. The last-40 form raised an input error on a record +with fixed QCs from 1965, where the proof's clock holds 21 QCs in 42 quarters +and only 19 in the last 40. `_minimum_current_period_qcs` already took 20 as a +ceiling. The session logged this as +`us:oasdi-insured-subsequent-special-long-period`. It is a statute against a +regulation, which is the pattern in d1920, so the refusal stands until Max +rules that pattern. + +### The lower date on an unknown ending + +Round 16 held the upper date to a filling with the reported start, and left +the lower date as each ending's favorable placement. An invented woman born +1960-02-02 has annual QCs 1995:3, four in each of 1996 to 1999, 2000:1, four +in each of 2001 to 2004 and 2005:3, an established period from 2000-01-01 and +an UNKNOWN ending. Of 64 placements, 16 keep the 2000Q1 start, and each puts +the 2000 QC in that quarter. An ending of 2005-12-31 then leaves those +placements a best date of 2009-12-31. At `e9f4140c` DISABILITY reported a lower +date of 2010-03-31, which needs that QC after 2000Q1 and so a later start. A +frozen OP12 exit overstates its lower date the same way. + +`_settle_lower_date` now searches fillings that keep the reported start, and +refuses by name unless each ending reaches the lower date. It runs on the +lower credits, because a lower date comes from those credits, so an UNKNOWN +year reaches the same check. UNKNOWN priors reach it too. They include the +completion with only the listed periods, and that completion holds every +ending, so the search reads the person with OBSERVED provenance. A mutation +found that gap in the first version of this fix. +`_fillings_keeping_start` holds the search that `_settle_first_start` already +ran. + +### Oracle reach and bounds + +`test_computed_exactly_when_every_reading_agrees` writes the two readings out +from the source text, with no production helper, and requires a computed +result exactly where they agree on the status and the date. The stress +oracle's `under_31` now takes a reading, and `check` holds a computed result +to both on every subsequent-special declaration. The classification oracle +treats a filling as lawful if either reading insures it. +`test_poms_mary_brown_keeps_a_computed_date_last_insured` and +`test_twenty_qcs_short_of_half_the_period_compute` hold the rejected parse out +of the rule. A new +`check_unknown_ending` exhausts each ending's fillings on the reported start, +and requires the upper date to equal the best of them and the lower date not +to exceed the worst. + +A probe drew 4,500 stress declarations with an UNKNOWN ending, each with known +and UNKNOWN priors, and they ran the search 1,440 times. One record needs a +different filling for each ending, and +`test_a_record_can_need_a_different_filling_for_each_ending` pins it. No search +reached an ending with no date, so +`test_an_ending_with_no_date_reaches_nothing` runs on written-out dates. + +A wide search drew 5,100 invented declarations from fresh seeds across the four +stress generators and both unknown-ending checks, and every check held: 3,014 +computed, 1,903 raised `InvalidFamilyInput`, and 183 refused by name. + +All 22 mutations of this round die at the final source bytes +(`round_17_mutations` in `docs/design/track_b_insured_status_mutations.json`), +and they ran against every insured status module. They include the three that +survived Sol's twelfth review: `count_upper_uses_minimum`, +`fully_count_lower_uses_maximum` and `omit_last_witness_for_ending`. Two early +mutations, `long_ignores_fully` and `long_drops_ignore_flag`, proved equivalent +across the 166,080 combinations above, so the clause they changed left the +source and they left the list. Against `e9f4140c`, 38 of the 261 tests in the +three changed modules fail. + +These tests execute the invariants this round adds: + +- a long subsequent-special period computes exactly where both readings + agree, and otherwise refuses by name with its row and weight + (`test_computed_exactly_when_every_reading_agrees`, + `test_a_long_period_refuses_where_its_readings_differ`, + `test_a_later_date_last_insured_can_turn_on_a_reading`, + `test_counting_the_prior_quarters_reaches_the_same_refusal`, and both + oracles); +- no reading's conflict becomes an input error + (`test_an_established_period_keeps_its_row`, + `test_an_age_62_fully_request_keeps_its_row`, + `test_unknown_prior_history_keeps_its_row_on_the_whole_period`, + `test_classification_oracle_subsequent_long_period`); +- every period ending reaches the reported lower date on a filling with the + reported start (`test_every_ending_must_reach_the_lower_date`, + `test_a_frozen_exit_reaches_the_same_check`, + `test_unknown_years_reach_the_same_check`, + `test_unknown_prior_history_reaches_the_same_check`, + `test_each_ending_can_reach_the_date_on_its_own_filling`, + `test_a_record_can_need_a_different_filling_for_each_ending`, + `test_an_ending_with_no_date_reaches_nothing`, `check_unknown_ending`); +- a fixed start needs no placement search + (`test_a_fixed_start_needs_no_placement_search`). + ## Not in scope No real data, population evaluation, baseline claiming hazard, behavioral diff --git a/docs/design/track_b_insured_status_mutations.json b/docs/design/track_b_insured_status_mutations.json index 88baaef26..f502de3dd 100644 --- a/docs/design/track_b_insured_status_mutations.json +++ b/docs/design/track_b_insured_status_mutations.json @@ -5829,5 +5829,500 @@ "tests/test_track_b_insured_status_status_stress.py": "73ba47c4de99479bfb416bb82dd807d5b03a3f4529a378e4802ded2053adec7d" }, "round_16_replay": "Write round_16_runner_source to scratch/review/run_round16_named.py. For each round_16_mutations record, write name/source_sha256/changes to its spec_path, then execute its exact command. Mutations apply only in memory.", - "round_16_final_source_sha256": "3fed28da694474236b63ff99a1d42576994de87a81297ba6f416f4d6fdd2a25e" + "round_16_final_source_sha256": "3fed28da694474236b63ff99a1d42576994de87a81297ba6f416f4d6fdd2a25e", + "round_17_mutations": [ + { + "name": "drop_long_refusal", + "source_sha256": "e66a554124b389e2d5abfed66ad4eef317cc6bf40ed09d055e5bed4389e32d04", + "changes": [ + { + "before": " if long_period and not best[1][0]:\n", + "after": " if False:\n" + } + ], + "spec_path": "scratch/review/round17-mutation-drop_long_refusal.json", + "log": "scratch/review/round17-mutation-drop_long_refusal.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round17 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round17 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND17_MUTATION=scratch/review/round17-mutation-drop_long_refusal.json .venv/bin/python scratch/review/run_round17_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_17.py::test_a_long_period_refuses_where_its_readings_differ[None-1991]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "refuse_even_when_insured", + "source_sha256": "e66a554124b389e2d5abfed66ad4eef317cc6bf40ed09d055e5bed4389e32d04", + "changes": [ + { + "before": " if long_period and not best[1][0]:\n", + "after": " if long_period:\n" + } + ], + "spec_path": "scratch/review/round17-mutation-refuse_even_when_insured.json", + "log": "scratch/review/round17-mutation-refuse_even_when_insured.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round17 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round17 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND17_MUTATION=scratch/review/round17-mutation-refuse_even_when_insured.json .venv/bin/python scratch/review/run_round17_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_17.py::test_twenty_of_forty_needs_no_reading" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "long_threshold_twenty", + "source_sha256": "e66a554124b389e2d5abfed66ad4eef317cc6bf40ed09d055e5bed4389e32d04", + "changes": [ + { + "before": " >= len(elapsed) // 2\n", + "after": " >= 20\n" + } + ], + "spec_path": "scratch/review/round17-mutation-long_threshold_twenty.json", + "log": "scratch/review/round17-mutation-long_threshold_twenty.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round17 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round17 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND17_MUTATION=scratch/review/round17-mutation-long_threshold_twenty.json .venv/bin/python scratch/review/run_round17_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_17.py::test_twenty_qcs_short_of_half_the_period_compute" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "long_threshold_above_half", + "source_sha256": "e66a554124b389e2d5abfed66ad4eef317cc6bf40ed09d055e5bed4389e32d04", + "changes": [ + { + "before": " >= len(elapsed) // 2\n", + "after": " >= len(elapsed) // 2 + 1\n" + } + ], + "spec_path": "scratch/review/round17-mutation-long_threshold_above_half.json", + "log": "scratch/review/round17-mutation-long_threshold_above_half.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round17 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round17 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND17_MUTATION=scratch/review/round17-mutation-long_threshold_above_half.json .venv/bin/python scratch/review/run_round17_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_17.py::test_a_long_period_refuses_where_its_readings_differ[None-1991]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "long_counts_last_40", + "source_sha256": "e66a554124b389e2d5abfed66ad4eef317cc6bf40ed09d055e5bed4389e32d04", + "changes": [ + { + "before": " & set(elapsed)\n", + "after": " & set(elapsed[-40:])\n" + } + ], + "spec_path": "scratch/review/round17-mutation-long_counts_last_40.json", + "log": "scratch/review/round17-mutation-long_counts_last_40.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round17 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round17 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND17_MUTATION=scratch/review/round17-mutation-long_counts_last_40.json .venv/bin/python scratch/review/run_round17_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_17.py::test_a_long_period_refuses_where_its_readings_differ[None-1991]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "long_keeps_last_treatment", + "source_sha256": "e66a554124b389e2d5abfed66ad4eef317cc6bf40ed09d055e5bed4389e32d04", + "changes": [ + { + "before": "long_period = long_period or (", + "after": "long_period = (" + } + ], + "spec_path": "scratch/review/round17-mutation-long_keeps_last_treatment.json", + "log": "scratch/review/round17-mutation-long_keeps_last_treatment.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round17 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round17 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND17_MUTATION=scratch/review/round17-mutation-long_keeps_last_treatment.json .venv/bin/python scratch/review/run_round17_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_17.py::test_a_long_period_refuses_where_its_readings_differ[None-1991]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "long_keeps_excluded_world_only", + "source_sha256": "e66a554124b389e2d5abfed66ad4eef317cc6bf40ed09d055e5bed4389e32d04", + "changes": [ + { + "before": " long_period = long_period or (\n", + "after": " long_period = long_period or use_periods and (\n" + } + ], + "spec_path": "scratch/review/round17-mutation-long_keeps_excluded_world_only.json", + "log": "scratch/review/round17-mutation-long_keeps_excluded_world_only.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round17 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round17 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND17_MUTATION=scratch/review/round17-mutation-long_keeps_excluded_world_only.json .venv/bin/python scratch/review/run_round17_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_17.py::test_counting_the_prior_quarters_reaches_the_same_refusal" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "proof_keeps_last_40", + "source_sha256": "e66a554124b389e2d5abfed66ad4eef317cc6bf40ed09d055e5bed4389e32d04", + "changes": [ + { + "before": " window, required = elapsed, max(6, len(elapsed) // 2)\n return len(set(window) & assigned) >= required\n", + "after": " window, required = elapsed[-40:], max(6, min(40, len(elapsed)) // 2)\n return len(set(window) & assigned) >= required\n" + } + ], + "spec_path": "scratch/review/round17-mutation-proof_keeps_last_40.json", + "log": "scratch/review/round17-mutation-proof_keeps_last_40.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round17 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round17 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND17_MUTATION=scratch/review/round17-mutation-proof_keeps_last_40.json .venv/bin/python scratch/review/run_round17_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_17.py::test_unknown_prior_history_keeps_its_row_on_the_whole_period" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "drop_lower_settlement", + "source_sha256": "e66a554124b389e2d5abfed66ad4eef317cc6bf40ed09d055e5bed4389e32d04", + "changes": [ + { + "before": " if dli is not None and dli.lower is not None:\n", + "after": " if False:\n" + } + ], + "spec_path": "scratch/review/round17-mutation-drop_lower_settlement.json", + "log": "scratch/review/round17-mutation-drop_lower_settlement.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round17 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round17 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND17_MUTATION=scratch/review/round17-mutation-drop_lower_settlement.json .venv/bin/python scratch/review/run_round17_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_17.py::test_every_ending_must_reach_the_lower_date[None-None]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "lower_skips_unknown_prior", + "source_sha256": "e66a554124b389e2d5abfed66ad4eef317cc6bf40ed09d055e5bed4389e32d04", + "changes": [ + { + "before": " if dli is not None and dli.lower is not None:\n", + "after": " if dli is not None and dli.lower is not None and not prior_unknown:\n" + } + ], + "spec_path": "scratch/review/round17-mutation-lower_skips_unknown_prior.json", + "log": "scratch/review/round17-mutation-lower_skips_unknown_prior.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round17 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round17 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND17_MUTATION=scratch/review/round17-mutation-lower_skips_unknown_prior.json .venv/bin/python scratch/review/run_round17_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_17.py::test_unknown_prior_history_reaches_the_same_check[None]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "lower_keeps_unknown_provenance", + "source_sha256": "e66a554124b389e2d5abfed66ad4eef317cc6bf40ed09d055e5bed4389e32d04", + "changes": [ + { + "before": " person = replace(\n person, prior_disability_periods_provenance=EarningsProvenance.OBSERVED\n )\n # Source conflict us:oasdi-insured-one-filling-first-start\n if _start_fixed(person, credits, start, month, exit_month):\n return\n", + "after": " # Source conflict us:oasdi-insured-one-filling-first-start\n if _start_fixed(person, credits, start, month, exit_month):\n return\n" + } + ], + "spec_path": "scratch/review/round17-mutation-lower_keeps_unknown_provenance.json", + "log": "scratch/review/round17-mutation-lower_keeps_unknown_provenance.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round17 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round17 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND17_MUTATION=scratch/review/round17-mutation-lower_keeps_unknown_provenance.json .venv/bin/python scratch/review/run_round17_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_17.py::test_unknown_prior_history_reaches_the_same_check[None]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "lower_uses_upper_world", + "source_sha256": "e66a554124b389e2d5abfed66ad4eef317cc6bf40ed09d055e5bed4389e32d04", + "changes": [ + { + "before": " person,\n lower,\n lo_start,\n month,\n coverage_end_month,\n dli.lower,\n", + "after": " person,\n upper,\n lo_start,\n month,\n coverage_end_month,\n dli.lower,\n" + } + ], + "spec_path": "scratch/review/round17-mutation-lower_uses_upper_world.json", + "log": "scratch/review/round17-mutation-lower_uses_upper_world.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round17 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round17 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND17_MUTATION=scratch/review/round17-mutation-lower_uses_upper_world.json .venv/bin/python scratch/review/run_round17_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_17.py::test_unknown_years_reach_the_same_check" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "lower_tests_upper_date", + "source_sha256": "e66a554124b389e2d5abfed66ad4eef317cc6bf40ed09d055e5bed4389e32d04", + "changes": [ + { + "before": " coverage_end_month,\n dli.lower,\n favored,\n", + "after": " coverage_end_month,\n dli.upper,\n favored,\n" + } + ], + "spec_path": "scratch/review/round17-mutation-lower_tests_upper_date.json", + "log": "scratch/review/round17-mutation-lower_tests_upper_date.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round17 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round17 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND17_MUTATION=scratch/review/round17-mutation-lower_tests_upper_date.json .venv/bin/python scratch/review/run_round17_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_17.py::test_a_record_can_need_a_different_filling_for_each_ending" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "any_ending_reaches", + "source_sha256": "e66a554124b389e2d5abfed66ad4eef317cc6bf40ed09d055e5bed4389e32d04", + "changes": [ + { + "before": " if min(reached) >= lowest:\n", + "after": " if max(reached) >= lowest:\n" + } + ], + "spec_path": "scratch/review/round17-mutation-any_ending_reaches.json", + "log": "scratch/review/round17-mutation-any_ending_reaches.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round17 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round17 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND17_MUTATION=scratch/review/round17-mutation-any_ending_reaches.json .venv/bin/python scratch/review/run_round17_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_17.py::test_every_ending_must_reach_the_lower_date[None-None]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "each_filling_alone", + "source_sha256": "e66a554124b389e2d5abfed66ad4eef317cc6bf40ed09d055e5bed4389e32d04", + "changes": [ + { + "before": " reached = found if reached is None else tuple(map(max, reached, found))\n", + "after": " reached = found\n" + } + ], + "spec_path": "scratch/review/round17-mutation-each_filling_alone.json", + "log": "scratch/review/round17-mutation-each_filling_alone.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round17 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round17 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND17_MUTATION=scratch/review/round17-mutation-each_filling_alone.json .venv/bin/python scratch/review/run_round17_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_17.py::test_each_ending_can_reach_the_date_on_its_own_filling" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "undated_ending_counts", + "source_sha256": "e66a554124b389e2d5abfed66ad4eef317cc6bf40ed09d055e5bed4389e32d04", + "changes": [ + { + "before": " last or date.min\n for _, last, _ in _period_outcomes(\n", + "after": " last or date.max\n for _, last, _ in _period_outcomes(\n" + } + ], + "spec_path": "scratch/review/round17-mutation-undated_ending_counts.json", + "log": "scratch/review/round17-mutation-undated_ending_counts.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round17 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round17 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND17_MUTATION=scratch/review/round17-mutation-undated_ending_counts.json .venv/bin/python scratch/review/run_round17_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_17.py::test_an_ending_with_no_date_reaches_nothing" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "lower_skips_fixed_start", + "source_sha256": "e66a554124b389e2d5abfed66ad4eef317cc6bf40ed09d055e5bed4389e32d04", + "changes": [ + { + "before": " if _start_fixed(person, credits, start, month, exit_month):\n return\n", + "after": "" + } + ], + "spec_path": "scratch/review/round17-mutation-lower_skips_fixed_start.json", + "log": "scratch/review/round17-mutation-lower_skips_fixed_start.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round17 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round17 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND17_MUTATION=scratch/review/round17-mutation-lower_skips_fixed_start.json .venv/bin/python scratch/review/run_round17_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_17.py::test_a_fixed_start_needs_no_placement_search" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "any_start_counts", + "source_sha256": "e66a554124b389e2d5abfed66ad4eef317cc6bf40ed09d055e5bed4389e32d04", + "changes": [ + { + "before": " if own_start == start:\n yield filling, completed\n", + "after": " yield filling, completed\n" + } + ], + "spec_path": "scratch/review/round17-mutation-any_start_counts.json", + "log": "scratch/review/round17-mutation-any_start_counts.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round17 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round17 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND17_MUTATION=scratch/review/round17-mutation-any_start_counts.json .venv/bin/python scratch/review/run_round17_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_17.py::test_every_ending_must_reach_the_lower_date[None-None]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "outcomes_undated", + "source_sha256": "e66a554124b389e2d5abfed66ad4eef317cc6bf40ed09d055e5bed4389e32d04", + "changes": [ + { + "before": " exit_month,\n (),\n True,\n )\n )\n reached =", + "after": " exit_month,\n (),\n False,\n )\n )\n reached =" + } + ], + "spec_path": "scratch/review/round17-mutation-outcomes_undated.json", + "log": "scratch/review/round17-mutation-outcomes_undated.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round17 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round17 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND17_MUTATION=scratch/review/round17-mutation-outcomes_undated.json .venv/bin/python scratch/review/run_round17_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_17.py::test_a_record_can_need_a_different_filling_for_each_ending" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "count_upper_uses_minimum", + "source_sha256": "e66a554124b389e2d5abfed66ad4eef317cc6bf40ed09d055e5bed4389e32d04", + "changes": [ + { + "before": " max(w[1] for w in witnesses),\n", + "after": " min(w[1] for w in witnesses),\n" + } + ], + "spec_path": "scratch/review/round17-mutation-count_upper_uses_minimum.json", + "log": "scratch/review/round17-mutation-count_upper_uses_minimum.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round17 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round17 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND17_MUTATION=scratch/review/round17-mutation-count_upper_uses_minimum.json .venv/bin/python scratch/review/run_round17_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status.py::test_decided_despite_unknown_reports_range_and_unknown_years" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "fully_count_lower_uses_maximum", + "source_sha256": "e66a554124b389e2d5abfed66ad4eef317cc6bf40ed09d055e5bed4389e32d04", + "changes": [ + { + "before": " min(w[7] for w in witnesses),\n", + "after": " max(w[7] for w in witnesses),\n" + } + ], + "spec_path": "scratch/review/round17-mutation-fully_count_lower_uses_maximum.json", + "log": "scratch/review/round17-mutation-fully_count_lower_uses_maximum.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round17 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round17 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND17_MUTATION=scratch/review/round17-mutation-fully_count_lower_uses_maximum.json .venv/bin/python scratch/review/run_round17_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_3_periods.py::test_ongoing_period_completion_status_and_count_bounds_are_sound" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "omit_last_witness_for_ending", + "source_sha256": "e66a554124b389e2d5abfed66ad4eef317cc6bf40ed09d055e5bed4389e32d04", + "changes": [ + { + "before": " found = tuple(zip(*(outcome[2] for outcome in outcomes), strict=True))\n", + "after": " found = tuple(zip(*(outcome[2] for outcome in outcomes[:-1]), strict=True))\n" + } + ], + "spec_path": "scratch/review/round17-mutation-omit_last_witness_for_ending.json", + "log": "scratch/review/round17-mutation-omit_last_witness_for_ending.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round17 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round17 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND17_MUTATION=scratch/review/round17-mutation-omit_last_witness_for_ending.json .venv/bin/python scratch/review/run_round17_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_year_counts_follow_the_returned_filling[5000026]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + } + ], + "round_17_runner_source": "\"\"\"Run named invented-data conformance tests with open-event auditing.\"\"\"\n\nimport hashlib\nimport json\nimport os\nfrom pathlib import Path\nimport sys\n\nCOUNTS = {\"restricted_opens\": 0, \"subprocess.Popen\": 0, \"os.system\": 0}\nBARRED = {\n \"gates.yaml\", \"adjusted_poverty.py\", \"rows.py\",\n \"ssa_trust_fund_interest_rates_2026.json\",\n \"urban2010_cola_comparison.md\", \"urban2010_fra68_comparison.md\",\n \"boomers2004_uniform_cut_comparison.md\", \"minimum_benefits_comparison.md\",\n \"m6_projection_engine.md\", \"mint8_table_user_guide.source.html\",\n \"test_anchor_provenance_erratum.py\",\n}\n\n\ndef audit(event, arguments):\n if event == \"open\" and isinstance(arguments[0], (str, bytes)):\n path = os.fsdecode(arguments[0])\n name = Path(path).name\n if (\n name in BARRED\n or name.startswith((\"adjusted_poverty.\", \"rows.\"))\n or \"/PolicyEngine/psid-data/\" in path\n or \"/microcosm-launch-evidence/\" in path\n or \"/dynasim-refs/\" in path\n or \"/claude-501/\" in path\n ):\n COUNTS[\"restricted_opens\"] += 1\n raise RuntimeError(path)\n elif event in (\"subprocess.Popen\", \"os.system\"):\n COUNTS[event] += 1\n\n\ndef main():\n for name in (\"POPULACE_DYNAMICS_PSID_DIR\", \"POPULACE_DYNAMICS_EPUF_DIR\"):\n assert os.environ[name] == \"/nonexistent/trackb-round17\"\n assert sys.argv[1:]\n assert all(\n not argument.startswith(\"tests/\") or \".py\" in argument\n for argument in sys.argv[1:]\n )\n sys.addaudithook(audit)\n from populace_dynamics.track_b import insured_status as insured\n\n source_path = Path(insured.__file__)\n original = source_path.read_bytes()\n baseline_path = os.environ.get(\"TRACKB_ROUND16_SOURCE\")\n if baseline_path:\n baseline = Path(baseline_path).read_bytes()\n exec(compile(baseline, str(source_path), \"exec\"), insured.__dict__)\n print(\"BASELINE\", hashlib.sha256(baseline).hexdigest(), flush=True)\n spec_path = os.environ.get(\"TRACKB_ROUND17_MUTATION\")\n if spec_path:\n spec = json.loads(Path(spec_path).read_text())\n assert hashlib.sha256(original).hexdigest() == spec[\"source_sha256\"]\n source = original.decode()\n for change in spec[\"changes\"]:\n assert source.count(change[\"before\"]) == 1, change[\"before\"]\n source = source.replace(change[\"before\"], change[\"after\"], 1)\n exec(compile(source, str(source_path), \"exec\"), insured.__dict__)\n print(\"MUTATION\", spec[\"name\"], flush=True)\n import pytest\n\n try:\n return pytest.main(sys.argv[1:])\n finally:\n assert source_path.read_bytes() == original\n print(\"OPEN_AUDIT\", json.dumps(COUNTS, sort_keys=True), flush=True)\n\n\nif __name__ == \"__main__\":\n raise SystemExit(main())\n", + "round_17_note": "Round 17 ran 22 named mutations at the final source bytes against every insured status test module, and all 22 die. count_upper_uses_minimum, fully_count_lower_uses_maximum and omit_last_witness_for_ending survived Sol's twelfth review and die here. long_ignores_fully and long_drops_ignore_flag proved equivalent across 166,080 combinations of birth, prior and query date, because half a long period exceeded the fully insured requirement by at least 10 QCs, so the clause and both mutations left, and test_half_a_long_period_clears_the_fully_insured_count holds the bound. proof_keeps_last_40 gained an edge test. lower_runs_with_unknown_prior exposed a real gap in the first version of this fix, and lower_skips_unknown_prior and lower_keeps_unknown_provenance replace it. lower_skips_fixed_start gained a record test. A probe drew 4,500 stress declarations with an UNKNOWN ending, each with known and UNKNOWN priors, and they ran the search 1,440 times. One record needs a different filling for each ending, so each_filling_alone dies on that record as well as on a written-out one. No search reached an ending with no date, so undated_ending_counts dies only on written-out dates.", + "round_17_test_sha256": { + "tests/test_track_b_insured_status_fix_round_17.py": "93042d14522bfcdc78a6525624ef7e903fa71531e6dbed9e68e61ed85ca27ef2", + "tests/test_track_b_insured_status_status_stress.py": "939636d32fd8281dcc428d8b5cba4c1a48ca0dcf00f56535175066001cd885f2", + "tests/test_track_b_insured_status_classification_oracle.py": "73c350cad6c47d4d1ebb205bcf946469e144aa1052dd54dcd5eb9bfe33bc5cbc" + }, + "round_17_replay": "Write round_17_runner_source to scratch/review/run_round17_named.py. For each round_17_mutations record, write name/source_sha256/changes to its spec_path, then execute its exact command. Mutations apply only in memory.", + "round_17_final_source_sha256": "e66a554124b389e2d5abfed66ad4eef317cc6bf40ed09d055e5bed4389e32d04" } diff --git a/docs/design/track_b_insured_status_rulespec_issue.md b/docs/design/track_b_insured_status_rulespec_issue.md index 47a6c6712..12e194988 100644 --- a/docs/design/track_b_insured_status_rulespec_issue.md +++ b/docs/design/track_b_insured_status_rulespec_issue.md @@ -123,6 +123,12 @@ case inventory, preserving its coverage labels. In particular: handling and creditable endpoint quarters. Preserve any source-versus-rule discrepancy documented by the Python lane; do not make the compiler imitate an erratum to force parity. +- Past 40 counted quarters a subsequent-special period has two readings: + half the whole period under 42 USC 423(c)(1)(B)(iii), and 20 of the last + 40 quarters under 20 CFR 404.130(d)(2). Execute both, and refuse where + they differ. The Python rule logs this as + `us:oasdi-insured-subsequent-special-long-period`, and d1920 holds the + pattern. - Explicitly refuse unsupported deemed, alien, military/railroad, Medicare, earned-basis, old-law and totalization inputs. A coverage refusal is not evidence that the published person's legal conclusion was negative. diff --git a/src/populace_dynamics/track_b/insured_status.py b/src/populace_dynamics/track_b/insured_status.py index 998ec4c7a..595f13be5 100644 --- a/src/populace_dynamics/track_b/insured_status.py +++ b/src/populace_dynamics/track_b/insured_status.py @@ -195,6 +195,7 @@ class InsuredUnsupportedReason(Enum): HISTORICAL_ENTITLEMENT = "entitlement_before_1968_unsupported" HISTORICAL_BLINDNESS = "blindness_before_1973_unsupported" HISTORICAL_SUBSEQUENT = "subsequent_special_before_1983_unsupported" + SUBSEQUENT_LONG_PERIOD = "subsequent_special_long_period_unsupported" ASSIGNMENT_COMPLEXITY = "disability_boundary_assignments_unsupported" @@ -1238,6 +1239,7 @@ def _witness( ): end = _qid(at) best = None + long_period = False # Source conflict us:oasdi-insured-prior-disability-favorable-disregard # CFR404.130(f): consider all prior periods or disregard all, favorably. for use_periods in ( @@ -1332,6 +1334,16 @@ def _witness( ) elif len(elapsed) > 40: window, required = elapsed[-40:], 20 + # Source conflict + # us:oasdi-insured-subsequent-special-long-period + # Half of over 40 quarters clears the fully count. + long_period = long_period or ( + len( + set(_assignment(rows, elapsed, boundary)) + & set(elapsed) + ) + >= len(elapsed) // 2 + ) else: window, required = elapsed, max(6, len(elapsed) // 2) candidates.append( @@ -1366,6 +1378,16 @@ def _witness( ) if best is None or score > best[0]: best = score, candidate + # Clause (iii) of Act 223(c)(1)(B) and 216(i)(3)(B) counts the whole period + # after age 21. 404.130(d)(2) caps it at "20 QCs out of 40 calendar + # quarters", and each 404.130 period ends with the tested quarter, so the + # cap repeats the 40-quarter rule. + if long_period and not best[1][0]: + _refuse( + InsuredUnsupportedReason.SUBSEQUENT_LONG_PERIOD, + "Readings of the subsequent-special cap differ on a period " + "of more than 40 quarters", + ) return best[1] @@ -1762,6 +1784,56 @@ def _improves(outcome, returned, last_insured): ) or (last or date.min) > (last_insured or date.min) +def _fillings_keeping_start( + person, credits, start, month, exit_month, favored +): + """Each annual placement and treatment that keeps the reported start.""" + horizon = _current_period_start_horizon(person, month) + witness = set( + _witness(person, credits, start, exit_month, InsuredTest.DISABILITY)[4] + ) + rows, _ = _world(person, credits, _qid(month), exit_month, False) + sensitive = _start_sensitive_years(person, horizon) + options = { + year: sorted( + _assignment_candidates(*row), + key=lambda choice: ( + len(set(choice) - witness), + len(set(choice) - favored), + choice, + ), + ) + for year, row in rows.items() + if year in sensitive and row[1] + } + for index, choices in enumerate(product(*options.values())): + if index == 4096: + _refuse( + InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, + "More than 4096 first-start annual placements", + ) + filling = dict(credits) + filling.update( + (year, (choice, 0)) + for year, choice in zip(options, choices, strict=True) + ) + for treatment in ( + (True, False) if person.prior_disability_periods else (None,) + ): + try: + completed, own_start = _with_current_period( + person, + filling, + month, + exit_month, + use_periods_only=treatment, + ) + except InvalidFamilyInput: + continue + if own_start == start: + yield filling, completed + + def _settle_first_start( person, credits, @@ -1831,74 +1903,34 @@ def _settle_first_start( "First insured start depends on annual placement " "or prior treatment", ) - witness = set( - _witness(person, credits, start, exit_month, InsuredTest.DISABILITY)[4] - ) - rows, _ = _world(person, credits, _qid(month), exit_month, False) - sensitive = _start_sensitive_years(person, horizon) - options = { - year: sorted( - _assignment_candidates(*row), - key=lambda choice: ( - len(set(choice) - witness), - len(set(choice) - favored), - choice, - ), - ) - for year, row in rows.items() - if year in sensitive and row[1] - } joint = kept = None - for index, choices in enumerate(product(*options.values())): - if index == 4096: - _refuse( - InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, - "More than 4096 first-start annual placements", + for filling, completed in _fillings_keeping_start( + person, credits, start, month, exit_month, favored + ): + outcomes = tuple( + _period_outcomes( + person, + completed, + start, + filling, + month, + exit_month, + kinds, + dated, ) - filling = dict(credits) - filling.update( - (year, (choice, 0)) - for year, choice in zip(options, choices, strict=True) ) - for treatment in ( - (True, False) if person.prior_disability_periods else (None,) + if joint is None and any( + outcome[:2] == (returned, last_insured) for outcome in outcomes ): - try: - completed, own_start = _with_current_period( - person, - filling, - month, - exit_month, - use_periods_only=treatment, - ) - except InvalidFamilyInput: - continue - if own_start != start: - continue - outcomes = tuple( - _period_outcomes( - person, - completed, - own_start, - filling, - month, - exit_month, - kinds, - dated, - ) - ) - if joint is None and any( - outcome[:2] == (returned, last_insured) for outcome in outcomes - ): - joint = filling - if joint is not None and reported is None: - return None, () - if reported is not None: - kept = _keep_favorable(kept, outcomes) - if joint is not None and _witness_ranks(kept) == _witness_ranks( - reported - ): - return joint, kept + joint = filling + if joint is not None and reported is None: + return None, () + if reported is not None: + kept = _keep_favorable(kept, outcomes) + if joint is not None and _witness_ranks(kept) == _witness_ranks( + reported + ): + return joint, kept # Every ending must still agree once each keeps the reported start. if joint is None or any( entry[0][0] != insured @@ -1913,6 +1945,50 @@ def _settle_first_start( return joint, kept +def _settle_lower_date( + person, credits, start, month, exit_month, lowest, favored +): + """Refuse a lower date that some period ending cannot reach. + + Each ending's favorable date can rest on a placement that moves the + reported start (404.321(a), RS00301.230). A lower bound speaks for every + ending, so each needs a filling that keeps the start and reaches it. + UNKNOWN priors include the completion with only the listed periods, and + that completion holds every ending. + """ + person = replace( + person, prior_disability_periods_provenance=EarningsProvenance.OBSERVED + ) + # Source conflict us:oasdi-insured-one-filling-first-start + if _start_fixed(person, credits, start, month, exit_month): + return + reached = None + for filling, completed in _fillings_keeping_start( + person, credits, start, month, exit_month, favored + ): + found = tuple( + last or date.min + for _, last, _ in _period_outcomes( + person, + completed, + start, + filling, + month, + exit_month, + (), + True, + ) + ) + reached = found if reached is None else tuple(map(max, reached, found)) + if min(reached) >= lowest: + return + _refuse( + InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, + "A period ending cannot reach the lower date last insured " + "with the reported first start", + ) + + def _current_period_completions(person, completed, start, month): """Every possible end quarter through query, plus continuation. @@ -2203,9 +2279,9 @@ def special_recent(quarter, clock=clock, assigned=assigned): elapsed = tuple(q for q in counted if q >= first) if len(elapsed) < 12: window, required = counted[-12:], 6 - elif len(elapsed) > 40: - window, required = elapsed[-40:], 20 else: + # Source conflict + # us:oasdi-insured-subsequent-special-long-period window, required = elapsed, max(6, len(elapsed) // 2) return len(set(window) & assigned) >= required @@ -2879,6 +2955,11 @@ def insured_status( True, include_zero=True, ) + favored = frozenset( + quarter + for row in favored_rows.values() + for quarter in _assign_qcs(*row) + ) kinds = tuple( kind for kind in (InsuredTest.FULLY, InsuredTest.CURRENTLY) @@ -2901,14 +2982,20 @@ def insured_status( if unknown or prior_unknown else tuple(candidates[kind] for kind in kinds) ), - favored=frozenset( - quarter - for row in favored_rows.values() - for quarter in _assign_qcs(*row) - ), + favored=favored, ) for kind, witnesses in zip(kinds, settled, strict=False): decisions[kind] = _status_decision(witnesses, witnesses) + if dli is not None and dli.lower is not None: + _settle_lower_date( + person, + lower, + lo_start, + month, + coverage_end_month, + dli.lower, + favored, + ) lo_rows, _ = _world( lo_person, placement or lower, diff --git a/tests/test_track_b_insured_status_classification_oracle.py b/tests/test_track_b_insured_status_classification_oracle.py index 6adf9a981..1976115cc 100644 --- a/tests/test_track_b_insured_status_classification_oracle.py +++ b/tests/test_track_b_insured_status_classification_oracle.py @@ -334,9 +334,10 @@ def _ordinary_routes( ) if len(elapsed) < 12: window, needed = _lookback(start, 12, periods, used), 6 - elif len(elapsed) > 40: - window, needed = frozenset(elapsed[-40:]), 20 else: + # Past 40 quarters a filling stays lawful on the Act's whole + # period, and the capped reading is 20_of_40 above (source + # conflict us:oasdi-insured-subsequent-special-long-period). window, needed = frozenset(elapsed), max(6, len(elapsed) // 2) if len(used & window) >= needed: routes.append("under31" if young else "subsequent_special") @@ -1086,6 +1087,37 @@ def test_classification_oracle_onset_quarter_and_credited_endpoint(flags): ) +@pytest.mark.parametrize("flags", FLAG_SETS) +@pytest.mark.parametrize("last_year_qcs", (1, 2, 3)) +@pytest.mark.parametrize("prior_unknown", (False, True)) +def test_classification_oracle_subsequent_long_period( + flags, last_year_qcs, prior_unknown +): + # 41 counted quarters, with 19, 20 or 21 QCs across the whole period. + counts = { + 1981: 3, + 1982: 3, + 1984: 4, + 1985: 4, + 1986: 4, + 1987: last_year_qcs, + } + prior = rule.DisabilityPeriod( + date(1983, 1, 15), date(1983, 6, 30), special_insured=True + ) + _check_classification( + _declaration( + onset=date(1991, 10, 15), + end=date(1992, 6, 30), + month=date(1992, 12, 1), + flags=flags, + periods=() if prior_unknown else (prior,), + prior_unknown=prior_unknown, + counts=counts, + ) + ) + + @pytest.mark.parametrize("flags", FLAG_SETS) def test_classification_oracle_six_qc_special_completions(flags): for prior_unknown, total in product((False, True), (5, 6)): diff --git a/tests/test_track_b_insured_status_fix_round_17.py b/tests/test_track_b_insured_status_fix_round_17.py new file mode 100644 index 000000000..240cbf5b9 --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_17.py @@ -0,0 +1,666 @@ +"""Round 17: the long subsequent-special period and the lower date. + +Verification class: statutory conformance on invented declarations; no +population, behavioral or forecast claim. + +Act 223(c)(1)(B)(iii) and 216(i)(3)(B)(iii) count "the quarters beginning +after such individual attained age 21", with no cap. 404.130(d)(2) adds "up to +a maximum of 20 QCs out of 40 calendar quarters". Past 40 counted quarters the +Act takes half the whole period and the regulation takes 20 of the last 40, and +the rule refuses by name wherever they differ (source conflict +us:oasdi-insured-subsequent-special-long-period). + +Each period ending's favorable date last insured can rest on a placement that +moves the reported start, so a lower bound must hold on every ending with that +start (404.321(a); RS 00301.230; source conflict +us:oasdi-insured-one-filling-first-start). +""" + +from dataclasses import replace +from datetime import date +from fractions import Fraction + +import pytest +from hypothesis import assume, example, given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as i +from populace_dynamics.track_b.gross_benefits import ( + InvalidFamilyInput, + count_family_outcomes, +) + +OBSERVED = i.EarningsProvenance.OBSERVED +UNKNOWN = i.EarningsProvenance.UNKNOWN +LONG = i.InsuredUnsupportedReason.SUBSEQUENT_LONG_PERIOD +ASSIGNMENT = i.InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY +WEIGHT = Fraction(5, 2) +BIRTH = date(1960, 2, 2) +ONSET = date(1991, 10, 15) +# The prior holds five full months, and neither endpoint is a QC. +SPECIAL = i.DisabilityPeriod( + date(1983, 1, 15), date(1983, 6, 30), special_insured=True +) +# 1981Q2 through 1991Q4 leaves 41 counted quarters, so half is 20. These 20 QCs +# all sit in that period, and only 19 sit in its last 40 quarters. +TWENTY = {1981: 3, 1982: 3, 1984: 4, 1985: 4, 1986: 4, 1987: 2} +# Nineteen QCs through 1999 leave the 2000 QC to reach 20 of 40, so a first +# insured quarter of 2000Q1 holds that QC there. +LOWER_ANNUAL = { + 1995: 3, + 1996: 4, + 1997: 4, + 1998: 4, + 1999: 4, + 2000: 1, + 2001: 4, + 2002: 4, + 2003: 4, + 2004: 4, + 2005: 3, +} +TWO_FILLINGS_ANNUAL = {1979: 3, 1980: 2, 1981: 1, 1982: 3, 1984: 4} + + +def _history(first, last, counts): + return { + year: ( + i.CoverageYear(OBSERVED, qc_count=counts.get(year, 0)) + if year >= 1978 + else i.CoverageYear(OBSERVED, qc_quarters=(False,) * 4) + ) + for year in range(first, last + 1) + } + + +def _person(*priors, **changes): + values = dict( + sex=i.Sex.FEMALE, + disability_onset=ONSET, + current_disability_period_established=False, + current_disability_period_provenance=OBSERVED, + prior_disability_periods=priors, + prior_disability_periods_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + values.update(changes) + return i.Person(BIRTH, **values) + + +def _established(*priors, **changes): + values = dict( + current_disability_period_established=True, + current_disability_period_end=date(1992, 6, 30), + current_disability_period_end_provenance=OBSERVED, + ) + values.update(changes) + return _person(*priors, **values) + + +def _rows(person, years, month, **options): + try: + return ( + i.evaluate_insured_status( + "case", + WEIGHT, + lambda: i.insured_status(person, years, month, **options), + ), + ) + except InvalidFamilyInput: + return () + + +def _refused_with(reason, person, years, month, **options): + rows = _rows(person, years, month, **options) + assert len(rows) == 1, rows + assert rows[0].result is None, rows[0].result + assert rows[0].unsupported.reason is reason + counted = count_family_outcomes(rows) + assert (counted.rows, counted.weight) == (1, WEIGHT) + assert (counted.unsupported_rows, counted.unsupported_weight) == ( + 1, + WEIGHT, + ) + + +def _result(person, years, month, **options): + rows = _rows(person, years, month, **options) + assert len(rows) == 1, rows + assert rows[0].result is not None, rows[0].unsupported + return rows[0].result + + +# The long subsequent-special period. + + +@pytest.mark.parametrize( + "exit_month,last", ((None, 1991), (date(1987, 12, 1), 1987)) +) +def test_a_long_period_refuses_where_its_readings_differ(exit_month, last): + _refused_with( + LONG, + _person(SPECIAL), + _history(1960, last, TWENTY), + date(1991, 10, 1), + coverage_end_month=exit_month, + ) + + +@pytest.mark.parametrize( + "test", (i.InsuredTest.ALL, i.InsuredTest.FULLY, i.InsuredTest.DISABILITY) +) +@pytest.mark.parametrize( + "exit_month,last", ((None, 1992), (date(1987, 12, 1), 1987)) +) +def test_an_established_period_keeps_its_row(test, exit_month, last): + # Only the whole-period reading insures this start, so no input error can + # stand: 404.321(a) gives the period a start on that reading. + _refused_with( + LONG, + _established(SPECIAL), + _history(1960, last, TWENTY), + date(1992, 12, 1), + coverage_end_month=exit_month, + test=test, + ) + + +@pytest.mark.parametrize( + "exit_month,last", ((None, 2022), (date(2009, 12, 1), 2009)) +) +def test_an_age_62_fully_request_keeps_its_row(exit_month, last): + counts = {**TWENTY, **dict.fromkeys(range(2000, 2010), 4)} + _refused_with( + LONG, + _established(SPECIAL), + _history(1960, last, counts), + date(2022, 3, 1), + coverage_end_month=exit_month, + test=i.InsuredTest.FULLY, + ) + + +def test_unknown_prior_history_keeps_its_row_on_the_whole_period(): + # Fixed QCs sit in 1965Q2, 1965Q3, 1967Q1 to Q3 and 1971Q3 to 1975Q2. The + # joint proof's clock drops uncredited quarters after the first possible + # prior, which leaves 42 quarters at 1975Q3. The 21 QCs meet half of those + # and only 19 sit in the last 40, so the proof must not reject the row. + person = i.Person( + date(1944, 2, 2), + sex=i.Sex.FEMALE, + disability_onset=date(1975, 8, 15), + current_disability_period_established=True, + current_disability_period_provenance=OBSERVED, + current_disability_period_end=date(1976, 6, 30), + current_disability_period_end_provenance=OBSERVED, + prior_disability_periods_provenance=UNKNOWN, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + flags = { + 1965: (False, True, True, False), + 1967: (True, True, True, False), + 1971: (False, False, True, True), + 1972: (True,) * 4, + 1973: (True,) * 4, + 1974: (True,) * 4, + 1975: (True, True, False, False), + } + years = { + year: ( + i.CoverageYear(OBSERVED, qc_quarters=flags.get(year, (False,) * 4)) + if year < 1978 + else i.CoverageYear(OBSERVED, qc_count=0) + ) + for year in range(1944, 1977) + } + assert len(_rows(person, years, date(1976, 12, 1))) == 1 + + +def test_fully_alone_needs_no_reading(): + result = _result( + _person(SPECIAL), + _history(1960, 1991, TWENTY), + date(1991, 10, 1), + test=i.InsuredTest.FULLY, + ) + assert result.fully.insured + assert result.dli is None + + +def test_a_period_without_special_status_opens_no_reading(): + result = _result( + _person(replace(SPECIAL, special_insured=False)), + _history(1960, 1991, TWENTY), + date(1991, 10, 1), + ) + assert not result.disability.insured + assert result.disability.rule == "disability_20_of_40" + + +def test_nineteen_qcs_fail_on_every_reading(): + short = {**TWENTY, 1987: 1} + result = _result( + _person(SPECIAL), _history(1960, 1991, short), date(1991, 10, 1) + ) + assert not result.disability.insured + + +def test_forty_counted_quarters_leave_one_reading(): + # 1991Q3 counts exactly 40 quarters, so the cap has nothing to do. + onset = date(1991, 8, 15) + result = _result( + _person(SPECIAL, disability_onset=onset), + _history(1960, 1991, TWENTY), + date(1991, 8, 1), + ) + assert result.disability.insured + assert result.disability.rule == "subsequent_special" + assert (result.disability.qc_count_lower, result.disability.required) == ( + 20, + 20, + ) + + +def test_twenty_of_forty_needs_no_reading(): + counts = {**TWENTY, 1987: 4, 1988: 4, 1989: 4, 1990: 4} + result = _result( + _person(SPECIAL), _history(1960, 1991, counts), date(1991, 10, 1) + ) + assert result.disability.insured + + +def test_a_later_date_last_insured_can_turn_on_a_reading(): + # The onset status holds on both readings, but past the 40-quarter rule's + # last date the whole-period reading still insures. + counts = {**TWENTY, 1987: 4, 1988: 4, 1989: 4, 1990: 4} + _refused_with( + LONG, + _person(SPECIAL), + _history(1960, 2003, counts), + date(2003, 1, 1), + ) + + +def test_twenty_qcs_short_of_half_the_period_compute(): + # The 20th QC arrives in 1994, when half the 53 counted quarters is 26, and + # the last 40 hold 10. Only a parse that drops "out of 40 calendar + # quarters" insures this record, and the rule takes no such parse. The 14 + # QCs through 1985 last meet half in 1988Q4, where 29 quarters reduce to 28. + counts = {1981: 3, 1982: 3, 1984: 4, 1985: 4, 1993: 4, 1994: 2} + result = _result( + _person(SPECIAL, disability_onset=date(1994, 11, 15)), + _history(1960, 1994, counts), + date(1994, 11, 1), + ) + assert not result.disability.insured + assert result.dli.upper == date(1988, 12, 31) + + +def test_poms_mary_brown_keeps_a_computed_date_last_insured(): + # RS 00301.147 C.1 prints 16 of 32 at the 11/2/82 onset. In 1983Q1 the 33 + # quarters reduce to 32. In 1983Q2 the 34 quarters need 17, and counting the + # prior's quarters under 404.130(f) leaves 20 QCs against 24. + patterns = { + 1970: "NNNC", + 1971: "NNCC", + 1972: "CCCN", + 1973: "CNNC", + 1974: "NNCC", + 1976: "CNNN", + 1978: "CCCC", + 1979: "CNNN", + 1980: "CNNN", + 1981: "CNNN", + 1982: "CCCN", + } + person = i.Person( + date(1950, 4, 16), + disability_onset=date(1982, 11, 2), + current_disability_period_established=False, + current_disability_period_provenance=OBSERVED, + prior_disability_periods=( + i.DisabilityPeriod( + date(1975, 5, 16), date(1978, 12, 31), special_insured=True + ), + ), + prior_disability_periods_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + years = { + year: ( + i.CoverageYear( + OBSERVED, + qc_quarters=tuple( + letter == "C" for letter in patterns.get(year, "NNNN") + ), + ) + if year < 1978 + else i.CoverageYear( + OBSERVED, qc_count=patterns.get(year, "").count("C") + ) + ) + for year in range(1950, 1984) + } + result = _result(person, years, date(1983, 6, 1)) + assert result.disability.insured + assert result.dli.upper == date(1983, 3, 31) + + +def test_counting_the_prior_quarters_reaches_the_same_refusal(): + # 404.130(f) counts the prior's quarters when that insures. Excluding them + # leaves 7 of 17, the last 40 quarters hold 16, and the whole 47 hold 23. + prior = i.DisabilityPeriod( + date(1983, 1, 15), date(1990, 6, 30), special_insured=True + ) + counts = {1981: 3, 1982: 4, 1983: 4, 1984: 4, 1985: 4, 1986: 4} + _refused_with( + LONG, + _person(prior, disability_onset=date(1992, 10, 15)), + _history(1960, 1992, counts), + date(1992, 10, 1), + ) + + +def _quarter(value): + return value.year * 4 + (value.month - 1) // 3 + + +@settings(max_examples=300, deadline=None, derandomize=True) +@given( + birth_year=st.integers(1905, 1990), + birth_month=st.integers(1, 12), + age=st.integers(31, 72), + month=st.sampled_from((1, 4, 7, 10)), + prior_age=st.integers(22, 30), + span=st.integers(0, 30), +) +def test_half_a_long_period_clears_the_fully_insured_count( + birth_year, birth_month, age, month, prior_age, span +): + # The refusal reads no fully insured test, because half of more than 40 + # counted quarters holds at least the 404.132 requirement. No QC sits in + # the prior here, which leaves the fewest counted quarters. + birth = date(birth_year, birth_month, 2) + at = date(birth_year + age, month, 1) + start = date(birth_year + prior_age, 3, 15) + end = date(birth_year + prior_age + span, 6, 30) + assume(end < at) + first = max(1937 * 4, birth_year * 4 + 84 + (birth_month - 1) // 3 + 1) + counted = [ + quarter + for quarter in range(first, _quarter(at) + 1) + if not _quarter(start) <= quarter <= _quarter(end) + ] + assume(len(counted) > 40) + person = i.Person(birth, sex=i.Sex.FEMALE) + required = i._requirement( + person, at, ((start, end),), onset=True, for_disability=True + ) + assert len(counted) // 2 >= required + + +def _placed(counts, at): + """Latest quarters through ``at``, the best for every suffix window.""" + return { + min(year * 4 + 3, at) - offset + for year, count in counts.items() + if year * 4 <= at + for offset in range(min(count, at - year * 4 + 1)) + } + + +def _insured(counts, at, reading): + """One reading of 404.130(a), (b), (d) and (f), from the source text.""" + credits = _placed(counts, at) + first = 1981 * 4 + 1 + prior = (1983 * 4, 1983 * 4 + 1) + for excluded in (prior, ()): + # 404.132: elapsed years stop at the year of the tested quarter. + elapsed_years = sum( + year != 1983 or not excluded for year in range(1982, at // 4) + ) + if len(credits) < max(6, min(40, elapsed_years)): + continue + counted = [ + quarter + for quarter in range(first - 40, at + 1) + if quarter not in excluded + ] + since_21 = [quarter for quarter in counted if quarter >= first] + recent = len(credits & set(counted[-40:])) + if recent >= 20: + return True + if len(since_21) < 12: + if len(credits & set(counted[-12:])) >= 6: + return True + elif len(since_21) <= 40: + if len(credits & set(since_21)) >= len(since_21) // 2: + return True + elif reading == "whole_period": + if len(credits & set(since_21)) >= len(since_21) // 2: + return True + return False + + +def _last_date(counts, at, reading): + return next( + ( + quarter + for quarter in range(at, 1984 * 4 - 1, -1) + if _insured(counts, quarter, reading) + ), + None, + ) + + +READINGS = ("last_40", "whole_period") + + +@settings(max_examples=250, deadline=None, derandomize=True) +@example(tail=(4, 4, 4, 2, 0, 0, 0), year=1991) +@example(tail=(4, 4, 4, 1, 0, 0, 0), year=1991) +@example(tail=(4, 4, 4, 4, 4, 4, 4), year=1991) +@example(tail=(4, 4, 4, 4, 4, 4, 4), year=2003) +@given( + tail=st.tuples(*[st.sampled_from((0, 1, 2, 4))] * 7), + year=st.integers(1989, 2003), +) +def test_computed_exactly_when_every_reading_agrees(tail, year): + counts = {1981: 3, 1982: 3} + counts.update(zip(range(1984, 1991), tail, strict=True)) + at = year * 4 + month = date(year, 1, 1) + answers = { + (_insured(counts, at, reading), _last_date(counts, at, reading)) + for reading in READINGS + } + rows = _rows( + _person(SPECIAL, disability_onset=date(year, 1, 15)), + _history(1960, year, counts), + month, + ) + assert len(rows) == 1 + if len(answers) > 1: + assert rows[0].result is None, (answers, rows[0]) + assert rows[0].unsupported.reason is LONG + else: + ((insured, last),) = answers + assert rows[0].result is not None, (answers, rows[0]) + assert rows[0].result.disability.insured == insured + upper = rows[0].result.dli.upper + assert (None if upper is None else _quarter(upper)) == last + + +# The lower date last insured. + + +def _lower_person(**changes): + values = dict( + disability_onset=date(2000, 1, 1), + current_disability_period_established=True, + current_disability_period_end=None, + current_disability_period_end_provenance=UNKNOWN, + ) + values.update(changes) + return _person(**values) + + +@pytest.mark.parametrize("through", (None, date(2005, 12, 31))) +@pytest.mark.parametrize("exit_month", (None, date(2011, 1, 1))) +def test_every_ending_must_reach_the_lower_date(through, exit_month): + # A 2005Q4 ending keeps the 2000Q1 start only on placements whose date is + # 2009Q4, so a lower date of 2010Q1 speaks for a filling that can't exist. + person = _lower_person() + if through is not None: + person = replace( + person, + current_disability_period_continues_through=through, + current_disability_period_continues_through_provenance=OBSERVED, + ) + _refused_with( + ASSIGNMENT, + person, + _history(1960, 2010, LOWER_ANNUAL), + date(2010, 1, 1), + test=i.InsuredTest.DISABILITY, + coverage_end_month=exit_month, + ) + + +@pytest.mark.parametrize( + "onset,month", ((date(1999, 6, 15), date(2012, 4, 1)),) +) +def test_an_earlier_onset_reaches_the_same_check(onset, month): + _refused_with( + ASSIGNMENT, + _lower_person(disability_onset=onset), + _history(1960, month.year, LOWER_ANNUAL), + month, + test=i.InsuredTest.DISABILITY, + ) + + +def test_a_frozen_exit_reaches_the_same_check(): + person = replace( + _lower_person(), + current_disability_period_continues_through=date(2000, 1, 1), + current_disability_period_continues_through_provenance=OBSERVED, + ) + _refused_with( + ASSIGNMENT, + person, + _history(1960, 2005, LOWER_ANNUAL), + date(2027, 1, 1), + test=i.InsuredTest.DISABILITY, + coverage_end_month=date(2005, 12, 1), + ) + + +@pytest.mark.parametrize("ending", (None, date(2005, 12, 31))) +def test_unknown_prior_history_reaches_the_same_check(ending): + # UNKNOWN priors include the completion with none, and that completion + # holds these placements, so the lower date has to hold for it too. + person = replace( + _lower_person(), prior_disability_periods_provenance=UNKNOWN + ) + if ending is not None: + person = replace( + person, + current_disability_period_end=ending, + current_disability_period_end_provenance=OBSERVED, + ) + _refused_with( + ASSIGNMENT, + person, + _history(1960, 2010, LOWER_ANNUAL), + date(2010, 1, 1), + test=i.InsuredTest.DISABILITY, + ) + + +def test_a_fixed_start_needs_no_placement_search(): + # Forty early QCs insure the start on every placement, and ten years of + # two QCs each hold more placements than the search would ever try. + counts = dict.fromkeys(range(1985, 1996), 4) + counts.update(dict.fromkeys(range(1996, 2006), 2)) + result = _result( + _lower_person(), + _history(1960, 2010, counts), + date(2010, 1, 1), + test=i.InsuredTest.DISABILITY, + ) + assert result.current_disability_period_start == date(2000, 1, 1) + assert result.dli.lower is not None + + +def _settle(monkeypatch, fillings, lowest): + """Run the settlement on written-out dates, one tuple per filling.""" + monkeypatch.setattr(i, "_start_fixed", lambda *args: False) + monkeypatch.setattr( + i, + "_fillings_keeping_start", + lambda *args: ((dates, None) for dates in fillings), + ) + monkeypatch.setattr( + i, + "_period_outcomes", + lambda person, completed, start, filling, *rest: ( + ((), last, ()) for last in filling + ), + ) + i._settle_lower_date( + _lower_person(), {}, date(2000, 1, 1), None, None, lowest, frozenset() + ) + + +def test_each_ending_can_reach_the_date_on_its_own_filling(monkeypatch): + early, late = date(2009, 12, 31), date(2010, 3, 31) + _settle(monkeypatch, ((early, late), (late, early)), late) + + +def test_a_record_can_need_a_different_filling_for_each_ending(): + # No one placement holds this date on every ending, and each ending holds + # it on a placement of its own, so the date stands. + result = _result( + _lower_person(disability_onset=date(1982, 8, 15)), + _history(1960, 1989, TWO_FILLINGS_ANNUAL), + date(1989, 1, 1), + test=i.InsuredTest.DISABILITY, + ) + assert result.dli.lower == date(1985, 9, 30) + + +def test_an_ending_with_no_date_reaches_nothing(monkeypatch): + with pytest.raises(i.InsuredConfigurationUnsupported): + _settle(monkeypatch, ((None, date(2010, 3, 31)),), date(2009, 12, 31)) + + +def test_a_lower_date_every_ending_reaches_computes(): + # Fixed credits leave one placement, so each ending keeps its own date. + counts = dict.fromkeys(range(1990, 2005), 4) + result = _result( + _lower_person(), + _history(1960, 2010, counts), + date(2010, 1, 1), + test=i.InsuredTest.DISABILITY, + ) + assert result.current_disability_period_start == date(2000, 1, 1) + assert result.dli.lower is not None + assert result.dli.lower <= result.dli.upper + + +def test_unknown_years_reach_the_same_check(): + # Unknown 2006 credits can only raise the date, so the lower world alone + # decides the bound, and it holds the same placements. + years = _history(1960, 2010, LOWER_ANNUAL) + years[2006] = i.CoverageYear(UNKNOWN) + _refused_with( + ASSIGNMENT, + _lower_person(), + years, + date(2010, 1, 1), + test=i.InsuredTest.DISABILITY, + ) diff --git a/tests/test_track_b_insured_status_status_stress.py b/tests/test_track_b_insured_status_status_stress.py index b9be2773f..da88ddba2 100644 --- a/tests/test_track_b_insured_status_status_stress.py +++ b/tests/test_track_b_insured_status_status_stress.py @@ -96,8 +96,16 @@ def recent(use, at, periods, length): return count -def under_31(birth, use, at, periods, special=False): - """404.130(c), (d): half the quarters after age 21, or 6 of 12.""" +LAST_40, WHOLE_PERIOD = READINGS = ("last_40", "whole_period") + + +def under_31(birth, use, at, periods, special=False, reading=LAST_40): + """404.130(c), (d): half the quarters after age 21, or 6 of 12. + + Past 40 counted quarters the Act's clause (iii) and 404.130(d)(2) part + ways (source conflict us:oasdi-insured-subsequent-special-long-period). + A computed result has to hold on both readings. + """ attained_21 = quarter(date(birth.year + 21, birth.month, birth.day)) if not special and at >= quarter( date(birth.year + 31, birth.month, birth.day) @@ -113,27 +121,34 @@ def under_31(birth, use, at, periods, special=False): ] if len(elapsed) < 12: return recent(use, at, periods, 12) >= 6 + if len(elapsed) > 40 and reading == WHOLE_PERIOD: + held = sum(candidate in use for candidate in elapsed) + return held >= len(elapsed) // 2 credited = sum(candidate in use for candidate in elapsed[-40:]) return credited >= max(6, min(len(elapsed), 40) // 2) -def disability(birth, credits, at, periods, blind, special=False): +def disability( + birth, credits, at, periods, blind, special=False, reading=LAST_40 +): use = usable(credits, at, periods) fully = len(use) >= requirement(birth, at // 4, periods) return fully and ( blind or recent(use, at, periods, 40) >= 20 - or under_31(birth, use, at, periods, special) + or under_31(birth, use, at, periods, special, reading) ) -def last_insured(birth, credits, at, periods, blind, special): +def last_insured(birth, credits, at, periods, blind, special, reading): """Latest quarter through the query that insures a potential onset.""" return max( ( candidate for candidate in range(min(credits, default=at), at + 1) - if disability(birth, credits, candidate, periods, blind, special) + if disability( + birth, credits, candidate, periods, blind, special, reading + ) ), default=None, ) @@ -148,7 +163,7 @@ def placements(annual): yield frozenset(credit for piece in pieces for credit in piece) -def lawful_fillings(case): +def lawful_fillings(case, reading=LAST_40): """Exhaust every filling before comparing to a public result. Each lawful filling gives its first start, three statuses, the best @@ -176,7 +191,13 @@ def lawful_fillings(case): candidate for candidate in range(quarter(onset), quarter(ending) + 1) if disability( - birth, credits, candidate, used, blind, special + birth, + credits, + candidate, + used, + blind, + special, + reading, ) ), None, @@ -214,7 +235,13 @@ def lawful_fillings(case): ( latest, last_insured( - birth, credits, at, periods, blind, special + birth, + credits, + at, + periods, + blind, + special, + reading, ), ), ), @@ -227,7 +254,13 @@ def lawful_fillings(case): currently_best[0], any( disability( - birth, credits, candidate, used, blind, special + birth, + credits, + candidate, + used, + blind, + special, + reading, ) for candidate in range(quarter(onset), at + 1) ), @@ -240,8 +273,10 @@ def lawful_fillings(case): return found -def public(case): +def public(case, **options): observed = rule.EarningsProvenance.OBSERVED + unknown_end = case.get("unknown_end", False) + unknown_prior = case.get("unknown_prior", False) person = rule.Person( case["birth"], sex=rule.Sex.FEMALE, @@ -249,15 +284,21 @@ def public(case): disability_onset=case["onset"], current_disability_period_established=True, current_disability_period_provenance=observed, - current_disability_period_end=case["ending"], - current_disability_period_end_provenance=observed, + current_disability_period_end=( + None if unknown_end else case["ending"] + ), + current_disability_period_end_provenance=( + rule.EarningsProvenance.UNKNOWN if unknown_end else observed + ), prior_disability_periods=tuple( rule.DisabilityPeriod( a, b, special_insured=case.get("special", False) ) for a, b in case["prior"] ), - prior_disability_periods_provenance=observed, + prior_disability_periods_provenance=( + rule.EarningsProvenance.UNKNOWN if unknown_prior else observed + ), sspa211_applies=False, sspa211_provenance=observed, dib_entitlement_month=case.get("entitlement"), @@ -270,7 +311,7 @@ def public(case): ) for year in range(case["birth"].year, case["month"].year + 1) } - return rule.insured_status(person, years, case["month"]) + return rule.insured_status(person, years, case["month"], **options) def declaration(seed): @@ -443,29 +484,94 @@ def check_diagnostics(case, result, fillings): def check(case): - fillings = lawful_fillings(case) + worlds = tuple( + lawful_fillings(case, reading) + for reading in (READINGS if case.get("special") else READINGS[:1]) + ) try: result = public(case) except rule.InsuredConfigurationUnsupported: return "refused" except InvalidFamilyInput as error: - assert not fillings, (case, error) + assert not any(worlds), (case, error) return "invalid" - assert fillings, (case, "computed an impossible establishment", result) actual = tuple( getattr(result, name).insured for name in ("fully", "currently", "disability") ) - expected = tuple( - any(filling[index] for filling in fillings) for index in (1, 2, 3) - ) - assert actual == expected, (case, actual, expected, result) start = quarter(result.current_disability_period_start) - for index, insured in enumerate(actual, 1): - assert not insured or any( - filling[0] == start and filling[index] for filling in fillings - ), (case, actual, start, fillings) - check_diagnostics(case, result, fillings) + for fillings in worlds: + assert fillings, (case, "computed an impossible start", result) + expected = tuple( + any(filling[index] for filling in fillings) for index in (1, 2, 3) + ) + assert actual == expected, (case, actual, expected, result) + for index, insured in enumerate(actual, 1): + assert not insured or any( + filling[0] == start and filling[index] for filling in fillings + ), (case, actual, start, fillings) + check_diagnostics(case, result, fillings) + return "computed" + + +def quarter_end(value): + year, number = divmod(value, 4) + month = 3 * number + 3 + return date(year, month, calendar.monthrange(year, month)[1]) + + +def check_unknown_ending(case, unknown_prior=False): + """Each ending's best date on the reported start must fit the range. + + UNKNOWN priors include the completion with none, which ``case`` then + declares, so its dates must also fit, though the upper end only bounds them. + """ + try: + result = public( + {**case, "unknown_end": True, "unknown_prior": unknown_prior}, + test=rule.InsuredTest.DISABILITY, + ) + except rule.InsuredConfigurationUnsupported: + return "refused" + except InvalidFamilyInput: + return "invalid" + if result.current_disability_period_start is None: + return "no start" + start = quarter(result.current_disability_period_start) + endings = [ + quarter_end(candidate) + for candidate in range(start, quarter(case["month"]) + 1) + ] + best = [] + for ending in (*endings, date(case["birth"].year + 70, 12, 31)): + own = [ + filling[6] + for filling in lawful_fillings({**case, "ending": ending}) + if filling[0] == start + ] + assert own or unknown_prior, (case, ending, result) + if own: + best.append(max(-1 if found is None else found for found in own)) + if not best: + return "no filling" + lower, upper = result.dli.lower, result.dli.upper + assert (-1 if lower is None else quarter(lower)) <= min(best), ( + case, + best, + result.dli, + ) + if unknown_prior: + assert upper is None or quarter(upper) >= max(best), ( + case, + best, + result.dli, + ) + else: + assert (-1 if upper is None else quarter(upper)) == max(best), ( + case, + best, + result.dli, + ) return "computed" @@ -529,3 +635,46 @@ def test_status_stress_under_31(seed): @given(seed=st.integers(0, 2**32 - 1)) def test_status_stress_subsequent_special(seed): check(subsequent_declaration(seed)) + + +def test_status_stress_a_lower_date_rests_on_the_reported_start(): + # A 2005Q4 ending reaches 2009Q4 and no later on the 2000Q1 start. + case = { + "birth": date(1960, 2, 2), + "onset": date(2000, 1, 1), + "ending": date(2005, 12, 31), + "month": date(2010, 1, 1), + "blind": False, + "prior": (), + "annual": { + 1995: 3, + 1996: 4, + 1997: 4, + 1998: 4, + 1999: 4, + 2000: 1, + 2001: 4, + 2002: 4, + 2003: 4, + 2004: 4, + 2005: 3, + }, + } + assert check_unknown_ending(case) == "refused" + + +@settings(max_examples=40, deadline=None, derandomize=True) +@given(seed=st.integers(0, 2**32 - 1)) +def test_status_stress_unknown_ending(seed): + case = declaration(seed) + check_unknown_ending({**case, "month": date(case["onset"].year + 2, 1, 1)}) + + +@settings(max_examples=40, deadline=None, derandomize=True) +@given(seed=st.integers(0, 2**32 - 1)) +def test_status_stress_unknown_ending_and_prior(seed): + case = {**declaration(seed), "prior": ()} + check_unknown_ending( + {**case, "month": date(case["onset"].year + 2, 1, 1)}, + unknown_prior=True, + ) From 129d44bd786f5f2eabc6c4b4853cdfc52158a463 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Sun, 1 Nov 2026 21:43:21 -0500 Subject: [PATCH 24/46] Hold UNKNOWN-prior results to a filling with no period in force Sol's thirteenth review of 88a0e7bc found that an UNKNOWN-prior lower date could rest on the current freeze. An added prior can take a credited quarter from that filling, and disregarding the prior drops the freeze too, so the date overstated a lawful history. The session's search then found the same defect in the status search. _fillings_keeping_start now gives each filling the record with no period in force under UNKNOWN priors, so both searches need one filling that keeps the start and attains the result there. Otherwise the row refuses by name and keeps its weight. An OBSERVED history keeps the freeze. The Mary Brown note now labels her date as derived, and the third parse falls on the explicit 40-quarter denominator. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 144 +++++++++- .../track_b_insured_status_mutations.json | 255 +++++++++++++++++- .../track_b/insured_status.py | 25 +- tests/README-tiers.md | 4 +- ...est_track_b_insured_status_fix_round_17.py | 7 +- ...est_track_b_insured_status_fix_round_18.py | 214 +++++++++++++++ ...st_track_b_insured_status_status_stress.py | 231 +++++++++++++++- tests/tier_counts.json | 2 +- 8 files changed, 851 insertions(+), 31 deletions(-) create mode 100644 tests/test_track_b_insured_status_fix_round_18.py diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index 140453938..fd14fb3d1 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -671,7 +671,7 @@ input. An input error propagates and creates no row. | Earnings require an increment after 2027 | `qc_amount_year_unsupported` | | Query before 1968; blind query before 1973; subsequent-special query before May 1983 | `entitlement_before_1968_unsupported`, `blindness_before_1973_unsupported`, `subsequent_special_before_1983_unsupported` | | A subsequent-special period past 40 counted quarters where half the whole period and 20 of the last 40 give different results | `subsequent_special_long_period_unsupported` | -| More than 4,096 disability-boundary combinations, unresolved ordinary-establishment overlap requiring more than 4,096 credit fillings, a first start that placement or prior treatment can move with no one filling supporting the returned result, or a lower date some ending can't reach on a filling with the reported start, after fixed overlap and every credit-count proof applicable to the surviving flag classes and foreign-credit declaration | `disability_boundary_assignments_unsupported` | +| More than 4,096 disability-boundary combinations, unresolved ordinary-establishment overlap requiring more than 4,096 credit fillings, a first start that placement or prior treatment can move with no one filling supporting the returned result, or a lower date some ending can't reach on a filling with the reported start, or, under UNKNOWN priors, a status or lower date no such filling attains with no period in force, after fixed overlap and every credit-count proof applicable to the surviving flag classes and foreign-credit declaration | `disability_boundary_assignments_unsupported` | The round-3 observable-trigger audit covers every `CoverageCondition`. An explicit condition continues to refuse under its own reason when the @@ -828,7 +828,7 @@ to a statutory sentence that does not state it. | --- | --- | | U1. UNKNOWN prior history can collapse to empty solely for impossibility validation when no earliest prior period could start insured, on/after birth, before current onset and the FRA end. | C320(b)(2) and C321(a) require an insured beginning without a still-earlier period. A216(i)(2)(A) permits "five full calendar months' duration or" DIB entitlement "for one or more months". The scan therefore admits a one-month period and maximum feasible earnings. Any possible ordinary or specialist starting route stops the proof. It establishes no observed empty-history fact. | | U2. UNKNOWN current establishment needs no new-period alternative if there is no medical onset or onset is at/after the statutory latest starting month. | A216(i)(2)(A)-(D) and C321 prohibit a period without disability or a nonempty pre-FRA interval. This removes an impossible new-period alternative only; it does not remove UNKNOWN prior history or an existing period's UNKNOWN administrative end. | -| U3. With unknown prior/current periods, true ordinary FULLY and CURRENTLY status under favorable all-period disregard decides true. A DISABILITY witness must also survive any current-establishment completion that ends the disability before that witness. | C320(a): "If benefits ... would be denied or reduced because of a period of disability, the period of disability will not be taken into consideration." B404.130(f) also permits counting all prior quarters if favorable. RS .120 requires all periods used or all disregarded; selective exclusions are not assumed. Specialist credit regimes are refused first. | +| U3. With unknown prior/current periods, true ordinary FULLY and CURRENTLY status under favorable all-period disregard decides true. A DISABILITY witness must also survive any current-establishment completion that ends the disability before that witness. With a reported start, one filling with that start must attain the status with no period in force (round 18). | C320(a): "If benefits ... would be denied or reduced because of a period of disability, the period of disability will not be taken into consideration." B404.130(f) also permits counting all prior quarters if favorable. RS .120 requires all periods used or all disregarded; selective exclusions are not assumed. Specialist credit regimes are refused first. | | U4. With unknown periods, fewer than six maximum QCs feasible by the immutable horizon proves establishment impossible after routes adding undeclared credits are excluded, except for blindness with a fully-route flag; it supplies no foreign-credit impossibility proof. | B404.110(b)(1) and B404.130(a) supply the ordinary six-QC prerequisite. U3's disregard cannot manufacture credits. UNKNOWN prior history disables both I15 and I16; current nonblindness cannot exclude a past blind prior. The separate emptiness proof tests the earliest prior as blind, and proves emptiness only if no earlier quarter can supply fully insured status or the alternate. It can preserve a fully-route refusal with empty recent windows only after the universal six-QC horizon floor clears (I17). Foreign credits, credit-route flags, and raw-earnings flags outside a complete direct envelope also preserve named refusals. The direct-envelope contract and declared pre1956 alternate still obey I9; that alternate flag adds no route beyond B4. Blindness alone supplies no credits and does not replace the ordinary fully insured prerequisite. | | U5. UNKNOWN earnings decide a requested Boolean only if all lower/upper ordinary earnings witnesses agree, under the permitted fixed-period/all-period treatments; an uncertain established start refuses only after at least one feasible filling survives. | B404.143 credits one QC for each increment, maximum four; B404.130 and .146 supply assignment/exclusion rules. Adding ordinary QCs cannot invalidate a fixed treatment. A derived start cannot be silently held fixed when the completion changes it. If a lower or upper representative cannot construct the declared period, but another single filling meets its end, continuity, and prior-overlap constraints, the public result is `unknown_earnings_years_decide_status`. If no ordinary filling can qualify by the declared end and all independent routes are impossible, it is an input error and creates no row. A deferred raw-conversion row uses temporary unknown fillings only for possibility, then retains its conversion refusal. Specialist possibilities and administrative-end candidates are considered separately. | | U6. UNKNOWN administrative end decides a status only when every end-quarter candidate from start through query/cap, plus permitted continuation, agrees, after applying any continuity lower bound. | A216(i)(2)(D) uses "whichever ... is the earlier"; C321(c)(3) includes "the last month for which you received benefits" after substantial gainful activity. Medical continuity cannot exclude early ends; a dated administrative continuity observation can. FRA/death caps limit the latest candidate and do not turn the unknown into a fact. Both ending and prior-history unknown facts remain disclosed when both are missing; UNKNOWN prior history uses the universal envelopes rather than inventing a derived current period to enumerate. The unchanged completion enumeration can include early endings rejected by I14 if declared concretely. Agreement across that larger set still implies agreement across every valid completion, while disagreement can preserve an extra refusal. An actual supplied end keeps its declared-date semantics; known ending provenance requires an ending date. | @@ -849,8 +849,8 @@ to a statutory sentence that does not state it. | B6. With known earnings and an UNKNOWN ending, returned count bounds include all end-candidate counts admitted by continuity; with entirely known facts they remain exact. | B404.120(b), .130(f), .146(d) distinguish credited endpoints and excluded interiors. All candidate quarters are enumerated, including early endpoints and capped-FRA candidates, subject to any continues-through observation; extrema therefore cover each completion. A continuity date is never inserted as a credited endpoint. No monotonic endpoint-count premise is used. | | B7. DLI lies through query without frozen exit, or through the pre-FRA-quarter/death horizon with frozen coverage; `None` is the bottom bound. A future exit cannot remove query censoring. | RS .148 defines DLI as "the last day in the last quarter" in which status is met and limits the search relative to FRA. B404.146(b) caps credits after death; A216(i)(2)(B) caps new periods. Future undeclared work is not assumed zero. Specialist routes are refused before this ordinary DLI calculation. | | B8. For a nonblind ordinary worker with no prior period, no DLI can lie more than 39 quarters after the last credited quarter. | B404.130(b)(2) requires "at least 20 QCs in the 40-quarter period ... ending with that quarter". After 39 later quarters no original QC remains. Blindness and prior-period special/exclusion routes disable this search shortcut; flagged or observable specialist routes refuse. | -| B9. With unknown periods the disregard DLI is a lower bound and the permitted query/FRA/death horizon is the upper bound; unknown SSPA applicability reduces any positive DLI lower bound to `None`. | C320(a) permits favorable disregard; B404.130(f) permits counting all prior-period quarters; RS .102 B.2 imposes an additional requirement. The bound does not infer a particular recovery or history. Exemption can recover the ordinary upper witness but cannot exceed the calendar horizon. | -| B10. UNKNOWN-ending DLI bounds include every end candidate. With an unresolved ongoing end, known prior history, and frozen-exit future horizon beyond query, the named DLI-horizon refusal remains. | C321(c)'s alternative endings and RS .148's last qualifying quarter permit different historical DLI witnesses. The candidate extrema bound all declared endings; no recovery beyond the query is inferred. Refusal covers the unobserved future administrative fact. Round 17 requires every ending to reach the lower date on a filling with the reported start, and refuses by name otherwise. | +| B9. With unknown periods the disregard DLI is a lower bound and the permitted query/FRA/death horizon is the upper bound; unknown SSPA applicability reduces any positive DLI lower bound to `None`. | C320(a) permits favorable disregard; B404.130(f) permits counting all prior-period quarters; RS .102 B.2 imposes an additional requirement. The bound does not infer a particular recovery or history. Exemption can recover the ordinary upper witness but cannot exceed the calendar horizon. Round 18 requires one filling with the reported start to reach the lower bound with no period in force, and refuses by name otherwise. | +| B10. UNKNOWN-ending DLI bounds include every end candidate. With an unresolved ongoing end, known prior history, and frozen-exit future horizon beyond query, the named DLI-horizon refusal remains. | C321(c)'s alternative endings and RS .148's last qualifying quarter permit different historical DLI witnesses. The candidate extrema bound all declared endings; no recovery beyond the query is inferred. Refusal covers the unobserved future administrative fact. Round 17 requires every ending to reach the lower date on a filling with the reported start, and refuses by name otherwise. Under UNKNOWN priors that filling reads no period in force, so no ending changes it (round 18). | | B11. At most 4,096 combinations of disability endpoint assignments are searched exactly, after any applicable impossibility proof. | B404.143(b) and RS .230 permit favorable assignment; B404.130(f) makes credited endpoints decisive. Fixed-overlap, six-QC, and I15's minimum-requirement checks precede `_boundary_variants`, including both alternate-path calls and UNKNOWN-prior-history feasibility. A remaining excess returns `disability_boundary_assignments_unsupported`; computational complexity is neither a statutory impossibility bound nor permission to retain an all-invalid declaration. | | B12. Ordinary counted windows have 13 quarters for current insurance and 40 for ordinary disability; young/subsequent special windows require half their elapsed quarters after dropping an odd remainder, with a six-QC minimum. The young-worker window holds at most 39 quarters. A subsequent-special period past 40 quarters computes only where the Act's whole period and 404.130(d)(2)'s 20 of 40 agree (round 17). | B404.120(a) says "13-quarter period"; .130(b) says "20 QCs in the 40-quarter period"; .130(c)-(d) and A216(i)(3)(B) supply the half-quarter, odd-remainder, and 6/12 alternatives. Blindness uses only the fully insured prerequisite. A fully-route flag must still leave a recent-rule witness or possible automatic pre1956 alternate where I16 applies; the pre1956 flag adds no route beyond that alternate. Specialist paths retaining possibility receive their named refusal. | | B13. Indexed annual QC amounts are at least the prior year's statutory increment and the rounded indexed 1978 amount, with nearest-$10 rounding and $5 ties upward. | A213(d)(2) chooses "the larger of" the prior increment and indexed amount, rounded to "the next higher multiple of $10" at a $5 tie. This exact parameter calculation has no disability or specialist alternative; input-domain checks require positive NAWI and a statutory prior increment. | @@ -2168,11 +2168,13 @@ readings: quarters of 404.130(b), so this reading adds nothing to that rule. A third parse takes 20 QCs anywhere in the period. The session rejected it. It -drops "out of 40 calendar quarters", and every period in 404.130 ends with the -tested quarter, so the test would stop asking about recent work. It would also -refuse RS 00301.147's Mary Brown, whose status the manual prints. Counting the -prior's quarters under 404.130(f) leaves 20 QCs in 48 quarters at 1983Q2, and -that parse alone would move the date last insured past 1983-03-31. +drops "out of 40 calendar quarters", the denominator 404.130(d)(2) states, and +every period in 404.130 ends with the tested quarter, so the test would stop +asking about recent work. RS 00301.147 doesn't decide this parse. It prints +Mary Brown's result at the November 1982 onset and no date last insured. This +rule derives her 1983-03-31 date: counting the prior's quarters under +404.130(f) leaves 20 QCs in 48 quarters at 1983Q2, and that parse alone would +move the derived date past 1983-03-31. Through round 16 the rule took the capped reading without logging it, and the stress oracle repeated it. An invented woman born 1960-02-02 has a special @@ -2222,10 +2224,8 @@ frozen OP12 exit overstates its lower date the same way. `_settle_lower_date` now searches fillings that keep the reported start, and refuses by name unless each ending reaches the lower date. It runs on the lower credits, because a lower date comes from those credits, so an UNKNOWN -year reaches the same check. UNKNOWN priors reach it too. They include the -completion with only the listed periods, and that completion holds every -ending, so the search reads the person with OBSERVED provenance. A mutation -found that gap in the first version of this fix. +year reaches the same check. UNKNOWN priors reach it too, and round 18 holds +them to a filling with no period in force. `_fillings_keeping_start` holds the search that `_settle_first_start` already ran. @@ -2290,6 +2290,124 @@ These tests execute the invariants this round adds: - a fixed start needs no placement search (`test_a_fixed_start_needs_no_placement_search`). +## Round 18 the current freeze under UNKNOWN priors + +Verification class: statutory conformance on invented declarations only. +This correction admits no population, behavioral, payment, or forecast claim. +Sol's thirteenth review of `88a0e7bc` raised one medium and one low, and both +reproduced. The session's search for the same defect then found it in the +status search. + +### The lower date on every prior history + +A declaration with UNKNOWN priors lists no period, and it stands for every +prior history. 404.130(f) and RS 00301.120 count all periods or disregard all +of them. `_settle_lower_date` read the current period back into its search, so +a filling could reach the lower date through the current freeze. Counting an +added prior can take a credited interior quarter from that filling, and +disregarding the added prior drops the freeze too. + +An invented woman born 1960-02-02 has annual QCs 1995:3, four in each of 1996 +to 1999, 2000:1, four in each of 2001 to 2004 and 2005:3, an established period +from 2000-01-01 through 2007-12-31, and UNKNOWN priors. For a January 2010 +query, `88a0e7bc` reported a date last insured of 2010-03-31 as the lower date. +A prior from 1999-04-01 through 1999-12-31 fits this record, because 17 QCs at +1999Q2 meet the fully insured test that historical blindness needs. Of 64 +placements, 16 keep the 2000Q1 start, and each puts the 2000 QC in that +quarter. Counting both periods leaves 19 QCs. Disregarding both leaves 19 in +the 40 quarters through 2010Q1 and 20 through 2009Q4, so that history's exact +date is 2009-12-31. A known ending, an UNKNOWN ending, UNKNOWN 2007 credits and +a frozen OP12 exit all reported a date past it. + +`_fillings_keeping_start` now gives each filling the record with no period in +force under UNKNOWN priors, and `_settle_lower_date` needs one such filling to +keep the start and reach the date. That filling speaks for every history. The +start under UNKNOWN priors is the onset, and the onset's witness stands on any +history that disregards all periods. The same disregard stays open at each +later quarter, so the date holds, whatever the period's ending. Where no +filling reaches the date, the row refuses with +`disability_boundary_assignments_unsupported` and keeps its weight. Lowering +the date instead would also be safe, and the session kept round 17's refusal. +The lower date itself needed no change: UNKNOWN priors already left it as the +date with no period in force, as B9 states. + +### The same search reached the statuses + +U3 lets a status under UNKNOWN priors stand on the all-period disregard. +`_settle_first_start` read the same search, so a filling with the reported +start could attain the status through the freeze. An invented woman born +1970-02-02 has annual QCs 1986:4, 1987:4, 1992:1, four in each of 1996 to 1999, +2000:1, 2001:4 and 2002:1, an established period from 2000-01-01 through +2002-12-31, and UNKNOWN priors. The 2000Q1 start needs the 2000 QC in that +quarter under the half-the-quarters test, and then the 13 quarters through +2003Q2 hold five QCs. For an April 2003 query, `88a0e7bc` reported CURRENTLY +true, because the freeze reaches QCs before 2000. A prior from 1996-01-01 +through 1999-12-31 takes all but its endpoint QCs, and no filling with the +2000Q1 start stays currently insured on that history. The shared change covers this +record: a filling now attains a status with no period in force, or the row +refuses by name. An OBSERVED empty history keeps the freeze, and both the status +and the date compute there. + +### The Mary Brown capture + +Round 17 leaned on RS 00301.147's Mary Brown to reject a third parse of the +long subsequent-special period. The capture prints her November 1982 onset +result and no date last insured, so the 1983-03-31 date is this rule's own +derivation and can't support the rejection. The text does: 404.130(d)(2) states +a denominator, "out of 40 calendar quarters", and the third parse drops it. The +round 17 section, its test comment and the logged row now say so, and the +ruling stands. + +### Oracle reach and bounds + +`check_every_history` adds three lawful priors to each record, exhausts the +placements with the reported start on each history and ending, and requires one +of them to hold each true status and reach the lower date. It imports no +production helper, and it requires a prior to begin fully insured. +`start_edge_declaration` redraws the tail of the two records above, so the +search runs near their boundary, and the oracle takes DISABILITY, CURRENTLY and +ALL requests, because an ALL request can refuse on another status first. +`test_status_stress_every_history_at_the_start_edge` fails at `88a0e7bc`. Its +first version drew records too far from that boundary and passed there, so +the generator changed. `test_status_stress_every_history` also passes at +`88a0e7bc`, so it stands only as a broad guard. +`test_status_stress_the_exact_date_on_that_history` and +`test_status_stress_the_status_on_that_history` hold both invented histories on +exhaustive placements. + +The wide search drew 550 invented declarations from fresh seeds, 400 from +`start_edge_declaration` and 150 from `declaration`, and ran each on both +ending kinds and three requests. All 3,300 checks held: 1,454 computed, 1,498 +refused by name, 318 raised `InvalidFamilyInput`, and 30 reported no start. + +All 11 mutations of this round die at the final source and test bytes +(`round_18_mutations` in `docs/design/track_b_insured_status_mutations.json`) +with no restricted open, and each ran through the insured status modules until +its first failure. `freeze_carries_unknown_priors` restores the search at +`88a0e7bc`, and `status_search_keeps_the_freeze` and +`date_search_keeps_the_freeze` restore it in one settlement function each. +Against `88a0e7bc`, 13 of the 85 tests in the three changed modules fail. + +These tests execute the invariants this round adds: + +- under UNKNOWN priors, a computed status or lower date holds on every lawful + prior history with the reported start + (`check_every_history` and its stress tests); +- one filling with the reported start attains it with no period in force, and + otherwise the row refuses by name and keeps its weight + (`test_the_freeze_cannot_carry_a_lower_date`, + `test_a_frozen_exit_cannot_carry_it_either`, + `test_a_status_resting_on_the_freeze_refuses`); +- the ending changes nothing under UNKNOWN priors + (`test_every_ending_shares_that_date`); +- a date or status with no period in force computes + (`test_a_date_with_no_period_in_force_computes`, + `test_a_status_with_no_period_in_force_computes`); +- a known history keeps the freeze (`test_a_known_history_keeps_the_freeze`, + `test_a_known_history_keeps_the_status`); +- a fixed start needs no placement search + (`test_a_fixed_start_needs_no_search_on_unknown_priors`). + ## Not in scope No real data, population evaluation, baseline claiming hazard, behavioral diff --git a/docs/design/track_b_insured_status_mutations.json b/docs/design/track_b_insured_status_mutations.json index f502de3dd..cd7c7988d 100644 --- a/docs/design/track_b_insured_status_mutations.json +++ b/docs/design/track_b_insured_status_mutations.json @@ -6324,5 +6324,258 @@ "tests/test_track_b_insured_status_classification_oracle.py": "73c350cad6c47d4d1ebb205bcf946469e144aa1052dd54dcd5eb9bfe33bc5cbc" }, "round_17_replay": "Write round_17_runner_source to scratch/review/run_round17_named.py. For each round_17_mutations record, write name/source_sha256/changes to its spec_path, then execute its exact command. Mutations apply only in memory.", - "round_17_final_source_sha256": "e66a554124b389e2d5abfed66ad4eef317cc6bf40ed09d055e5bed4389e32d04" + "round_17_final_source_sha256": "e66a554124b389e2d5abfed66ad4eef317cc6bf40ed09d055e5bed4389e32d04", + "round_18_mutations": [ + { + "name": "freeze_carries_unknown_priors", + "source_sha256": "a2f2e761041d2bf71622a46ce3cd466c49b6d5b6a92bff452552b34d65607118", + "changes": [ + { + "before": " yield filling, person if every_history else completed\n", + "after": " yield filling, completed\n" + } + ], + "spec_path": "scratch/review/round18-mutation-freeze_carries_unknown_priors.json", + "log": "scratch/review/round18-mutation-freeze_carries_unknown_priors.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round18 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round18 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND18_MUTATION=scratch/review/round18-mutation-freeze_carries_unknown_priors.json .venv/bin/python scratch/review/run_round18_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_18.py::test_the_freeze_cannot_carry_a_lower_date[known_end]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "every_filling_drops_the_period", + "source_sha256": "a2f2e761041d2bf71622a46ce3cd466c49b6d5b6a92bff452552b34d65607118", + "changes": [ + { + "before": " yield filling, person if every_history else completed\n", + "after": " yield filling, person\n" + } + ], + "spec_path": "scratch/review/round18-mutation-every_filling_drops_the_period.json", + "log": "scratch/review/round18-mutation-every_filling_drops_the_period.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round18 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round18 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND18_MUTATION=scratch/review/round18-mutation-every_filling_drops_the_period.json .venv/bin/python scratch/review/run_round18_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_18.py::test_a_known_history_keeps_the_freeze" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "every_history_reads_observed", + "source_sha256": "a2f2e761041d2bf71622a46ce3cd466c49b6d5b6a92bff452552b34d65607118", + "changes": [ + { + "before": " person.prior_disability_periods_provenance\n is EarningsProvenance.UNKNOWN\n )\n horizon = _current_period_start_horizon(person, month)\n witness = set(", + "after": " person.prior_disability_periods_provenance\n is EarningsProvenance.OBSERVED\n )\n horizon = _current_period_start_horizon(person, month)\n witness = set(" + } + ], + "spec_path": "scratch/review/round18-mutation-every_history_reads_observed.json", + "log": "scratch/review/round18-mutation-every_history_reads_observed.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round18 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round18 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND18_MUTATION=scratch/review/round18-mutation-every_history_reads_observed.json .venv/bin/python scratch/review/run_round18_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_18.py::test_the_freeze_cannot_carry_a_lower_date[known_end]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "status_search_keeps_the_freeze", + "source_sha256": "a2f2e761041d2bf71622a46ce3cd466c49b6d5b6a92bff452552b34d65607118", + "changes": [ + { + "before": " for filling, completed in _fillings_keeping_start(\n person, credits, start, month, exit_month, favored\n ):\n outcomes = tuple(\n", + "after": " for filling, completed in _fillings_keeping_start(\n person, credits, start, month, exit_month, favored\n ):\n completed = _complete_current_period(person, start)[0]\n outcomes = tuple(\n" + } + ], + "spec_path": "scratch/review/round18-mutation-status_search_keeps_the_freeze.json", + "log": "scratch/review/round18-mutation-status_search_keeps_the_freeze.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round18 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round18 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND18_MUTATION=scratch/review/round18-mutation-status_search_keeps_the_freeze.json .venv/bin/python scratch/review/run_round18_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_18.py::test_a_status_resting_on_the_freeze_refuses[False-InsuredTest.ALL]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "date_search_keeps_the_freeze", + "source_sha256": "a2f2e761041d2bf71622a46ce3cd466c49b6d5b6a92bff452552b34d65607118", + "changes": [ + { + "before": " for filling, completed in _fillings_keeping_start(\n person, credits, start, month, exit_month, favored\n ):\n found = tuple(\n", + "after": " for filling, completed in _fillings_keeping_start(\n person, credits, start, month, exit_month, favored\n ):\n completed = _complete_current_period(person, start)[0]\n found = tuple(\n" + } + ], + "spec_path": "scratch/review/round18-mutation-date_search_keeps_the_freeze.json", + "log": "scratch/review/round18-mutation-date_search_keeps_the_freeze.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round18 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round18 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND18_MUTATION=scratch/review/round18-mutation-date_search_keeps_the_freeze.json .venv/bin/python scratch/review/run_round18_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_18.py::test_the_freeze_cannot_carry_a_lower_date[known_end]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "drop_lower_settlement", + "source_sha256": "a2f2e761041d2bf71622a46ce3cd466c49b6d5b6a92bff452552b34d65607118", + "changes": [ + { + "before": " if dli is not None and dli.lower is not None:\n", + "after": " if False:\n" + } + ], + "spec_path": "scratch/review/round18-mutation-drop_lower_settlement.json", + "log": "scratch/review/round18-mutation-drop_lower_settlement.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round18 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round18 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND18_MUTATION=scratch/review/round18-mutation-drop_lower_settlement.json .venv/bin/python scratch/review/run_round18_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_18.py::test_the_freeze_cannot_carry_a_lower_date[known_end]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "lower_skips_unknown_prior", + "source_sha256": "a2f2e761041d2bf71622a46ce3cd466c49b6d5b6a92bff452552b34d65607118", + "changes": [ + { + "before": " if dli is not None and dli.lower is not None:\n", + "after": " if dli is not None and dli.lower is not None and not prior_unknown:\n" + } + ], + "spec_path": "scratch/review/round18-mutation-lower_skips_unknown_prior.json", + "log": "scratch/review/round18-mutation-lower_skips_unknown_prior.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round18 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round18 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND18_MUTATION=scratch/review/round18-mutation-lower_skips_unknown_prior.json .venv/bin/python scratch/review/run_round18_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_18.py::test_the_freeze_cannot_carry_a_lower_date[known_end]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "any_start_counts", + "source_sha256": "a2f2e761041d2bf71622a46ce3cd466c49b6d5b6a92bff452552b34d65607118", + "changes": [ + { + "before": " if own_start == start:\n yield filling, person if every_history else completed\n", + "after": " yield filling, person if every_history else completed\n" + } + ], + "spec_path": "scratch/review/round18-mutation-any_start_counts.json", + "log": "scratch/review/round18-mutation-any_start_counts.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round18 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round18 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND18_MUTATION=scratch/review/round18-mutation-any_start_counts.json .venv/bin/python scratch/review/run_round18_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_18.py::test_the_freeze_cannot_carry_a_lower_date[known_end]" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "lower_skips_fixed_start", + "source_sha256": "a2f2e761041d2bf71622a46ce3cd466c49b6d5b6a92bff452552b34d65607118", + "changes": [ + { + "before": " if _start_fixed(person, credits, start, month, exit_month):\n return\n reached = None\n", + "after": " reached = None\n" + } + ], + "spec_path": "scratch/review/round18-mutation-lower_skips_fixed_start.json", + "log": "scratch/review/round18-mutation-lower_skips_fixed_start.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round18 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round18 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND18_MUTATION=scratch/review/round18-mutation-lower_skips_fixed_start.json .venv/bin/python scratch/review/run_round18_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_18.py::test_a_fixed_start_needs_no_search_on_unknown_priors" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "first_start_skips_fixed_start", + "source_sha256": "a2f2e761041d2bf71622a46ce3cd466c49b6d5b6a92bff452552b34d65607118", + "changes": [ + { + "before": " if _start_fixed(person, credits, start, month, exit_month):\n return None, ()\n", + "after": "" + } + ], + "spec_path": "scratch/review/round18-mutation-first_start_skips_fixed_start.json", + "log": "scratch/review/round18-mutation-first_start_skips_fixed_start.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round18 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round18 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND18_MUTATION=scratch/review/round18-mutation-first_start_skips_fixed_start.json .venv/bin/python scratch/review/run_round18_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_18.py::test_a_fixed_start_needs_no_search_on_unknown_priors" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + }, + { + "name": "lower_tests_above_the_date", + "source_sha256": "a2f2e761041d2bf71622a46ce3cd466c49b6d5b6a92bff452552b34d65607118", + "changes": [ + { + "before": " if min(reached) >= lowest:\n", + "after": " if min(reached) > lowest:\n" + } + ], + "spec_path": "scratch/review/round18-mutation-lower_tests_above_the_date.json", + "log": "scratch/review/round18-mutation-lower_tests_above_the_date.log", + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round18 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round18 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=$PWD/src:$PWD TRACKB_ROUND18_MUTATION=scratch/review/round18-mutation-lower_tests_above_the_date.json .venv/bin/python scratch/review/run_round18_named.py -p no:xdist -p no:cacheprovider -q --tb=line -rf tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_18.py::test_a_date_with_no_period_in_force_computes" + ], + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + } + } + ], + "round_18_runner_source": "\"\"\"Run named invented-data conformance tests with open-event auditing.\"\"\"\n\nimport hashlib\nimport json\nimport os\nfrom pathlib import Path\nimport sys\n\nCOUNTS = {\"restricted_opens\": 0, \"subprocess.Popen\": 0, \"os.system\": 0}\nBARRED = {\n \"gates.yaml\", \"adjusted_poverty.py\", \"rows.py\",\n \"ssa_trust_fund_interest_rates_2026.json\",\n \"urban2010_cola_comparison.md\", \"urban2010_fra68_comparison.md\",\n \"boomers2004_uniform_cut_comparison.md\", \"minimum_benefits_comparison.md\",\n \"m6_projection_engine.md\", \"mint8_table_user_guide.source.html\",\n \"test_anchor_provenance_erratum.py\",\n}\n\n\ndef audit(event, arguments):\n if event == \"open\" and isinstance(arguments[0], (str, bytes)):\n path = os.fsdecode(arguments[0])\n name = Path(path).name\n if (\n name in BARRED\n or name.startswith((\"adjusted_poverty.\", \"rows.\"))\n or \"/PolicyEngine/psid-data/\" in path\n or \"/microcosm-launch-evidence/\" in path\n or \"/dynasim-refs/\" in path\n or \"/claude-501/\" in path\n ):\n COUNTS[\"restricted_opens\"] += 1\n raise RuntimeError(path)\n elif event in (\"subprocess.Popen\", \"os.system\"):\n COUNTS[event] += 1\n\n\ndef main():\n for name in (\"POPULACE_DYNAMICS_PSID_DIR\", \"POPULACE_DYNAMICS_EPUF_DIR\"):\n assert os.environ[name] == \"/nonexistent/trackb-round18\"\n assert sys.argv[1:]\n assert all(\n not argument.startswith(\"tests/\") or \".py\" in argument\n for argument in sys.argv[1:]\n )\n sys.addaudithook(audit)\n from populace_dynamics.track_b import insured_status as insured\n\n source_path = Path(insured.__file__)\n original = source_path.read_bytes()\n baseline_path = os.environ.get(\"TRACKB_ROUND16_SOURCE\")\n if baseline_path:\n baseline = Path(baseline_path).read_bytes()\n exec(compile(baseline, str(source_path), \"exec\"), insured.__dict__)\n print(\"BASELINE\", hashlib.sha256(baseline).hexdigest(), flush=True)\n spec_path = os.environ.get(\"TRACKB_ROUND18_MUTATION\")\n if spec_path:\n spec = json.loads(Path(spec_path).read_text())\n assert hashlib.sha256(original).hexdigest() == spec[\"source_sha256\"]\n source = original.decode()\n for change in spec[\"changes\"]:\n assert source.count(change[\"before\"]) == 1, change[\"before\"]\n source = source.replace(change[\"before\"], change[\"after\"], 1)\n exec(compile(source, str(source_path), \"exec\"), insured.__dict__)\n print(\"MUTATION\", spec[\"name\"], flush=True)\n import pytest\n\n try:\n return pytest.main(sys.argv[1:])\n finally:\n assert source_path.read_bytes() == original\n print(\"OPEN_AUDIT\", json.dumps(COUNTS, sort_keys=True), flush=True)\n\n\nif __name__ == \"__main__\":\n raise SystemExit(main())\n", + "round_18_note": "Round 18 mutations ran at the final source and test bytes against every insured status module. `freeze_carries_unknown_priors` restores the search at 88a0e7bc. `status_search_keeps_the_freeze` and `date_search_keeps_the_freeze` restore it in one settlement function each, so the status and date regressions bite apart. `lower_keeps_unknown_provenance` left the list because the replacement it changed left the source.", + "round_18_test_sha256": { + "tests/test_track_b_insured_status_fix_round_18.py": "c2d286f1080dea2b0170ff4302e4bca3a02650f77ee2fb6075702ab2c8101a49", + "tests/test_track_b_insured_status_status_stress.py": "95633236c57e370b98d307fe24ae6efc989a62042a7385d535210b575c08b0c8", + "tests/test_track_b_insured_status_fix_round_17.py": "9d7357bd0caf1915fd4b1cba8c8746aae2b54a48b4ce1d0dfe9b13c29625c2f8" + }, + "round_18_replay": "Write round_18_runner_source to scratch/review/run_round18_named.py. For each round_18_mutations record, write name/source_sha256/changes to its spec_path, then execute its exact command. Mutations apply only in memory.", + "round_18_final_source_sha256": "a2f2e761041d2bf71622a46ce3cd466c49b6d5b6a92bff452552b34d65607118" } diff --git a/src/populace_dynamics/track_b/insured_status.py b/src/populace_dynamics/track_b/insured_status.py index 595f13be5..02bc72fcd 100644 --- a/src/populace_dynamics/track_b/insured_status.py +++ b/src/populace_dynamics/track_b/insured_status.py @@ -1787,7 +1787,18 @@ def _improves(outcome, returned, last_insured): def _fillings_keeping_start( person, credits, start, month, exit_month, favored ): - """Each annual placement and treatment that keeps the reported start.""" + """Each annual placement and treatment that keeps the reported start. + + UNKNOWN priors stand for every prior history, and counting an added prior + can take a credited quarter from the record. Only disregarding all periods + speaks for every history (404.130(f), RS00301.120), and that drops the + current period too, whatever its ending. Each filling then reads the + person with no period in force. + """ + every_history = ( + person.prior_disability_periods_provenance + is EarningsProvenance.UNKNOWN + ) horizon = _current_period_start_horizon(person, month) witness = set( _witness(person, credits, start, exit_month, InsuredTest.DISABILITY)[4] @@ -1831,7 +1842,7 @@ def _fillings_keeping_start( except InvalidFamilyInput: continue if own_start == start: - yield filling, completed + yield filling, person if every_history else completed def _settle_first_start( @@ -1863,7 +1874,8 @@ def _settle_first_start( attains the result. Ties go to ``favored``, the quarters the excluded world credits, so the returned filling keeps a year's credits where it can. A year that cannot move the start stays flexible, so each status - still places it favorably. + still places it favorably. Under UNKNOWN priors a filling attains a status + only with no period in force (see ``_fillings_keeping_start``). The same limit binds what a status reports. Its favorable count and assignment can rest on a placement that would move the start, so @@ -1953,12 +1965,9 @@ def _settle_lower_date( Each ending's favorable date can rest on a placement that moves the reported start (404.321(a), RS00301.230). A lower bound speaks for every ending, so each needs a filling that keeps the start and reaches it. - UNKNOWN priors include the completion with only the listed periods, and - that completion holds every ending. + UNKNOWN priors leave one outcome for each filling, the record with no + period in force, and it speaks for every ending and prior history. """ - person = replace( - person, prior_disability_periods_provenance=EarningsProvenance.OBSERVED - ) # Source conflict us:oasdi-insured-one-filling-first-start if _start_fixed(person, credits, start, month, exit_month): return diff --git a/tests/README-tiers.md b/tests/README-tiers.md index 1b15bb443..86045728b 100644 --- a/tests/README-tiers.md +++ b/tests/README-tiers.md @@ -39,9 +39,9 @@ pytest --collect-only -q -m oracle_policyengine | tail -1 | Tier | Tests at HEAD | |---|---:| -| `unit` | 22,103 | +| `unit` | 22,127 | | `artifact` | 4,271 | | `integration_psid` | 1,471 | | `reproduction_legacy` | 520 | | `oracle_policyengine` | 308 | -| **Total** | **28,673** | +| **Total** | **28,697** | diff --git a/tests/test_track_b_insured_status_fix_round_17.py b/tests/test_track_b_insured_status_fix_round_17.py index 240cbf5b9..9c355d680 100644 --- a/tests/test_track_b_insured_status_fix_round_17.py +++ b/tests/test_track_b_insured_status_fix_round_17.py @@ -299,9 +299,10 @@ def test_twenty_qcs_short_of_half_the_period_compute(): def test_poms_mary_brown_keeps_a_computed_date_last_insured(): - # RS 00301.147 C.1 prints 16 of 32 at the 11/2/82 onset. In 1983Q1 the 33 - # quarters reduce to 32. In 1983Q2 the 34 quarters need 17, and counting the - # prior's quarters under 404.130(f) leaves 20 QCs against 24. + # RS 00301.147 C.1 prints 16 of 32 at the 11/2/82 onset and no date last + # insured, so this rule derives the date below. In 1983Q1 the 33 quarters + # reduce to 32. In 1983Q2 the 34 quarters need 17, and counting the prior's + # quarters under 404.130(f) leaves 20 QCs against 24. patterns = { 1970: "NNNC", 1971: "NNCC", diff --git a/tests/test_track_b_insured_status_fix_round_18.py b/tests/test_track_b_insured_status_fix_round_18.py new file mode 100644 index 000000000..d22011b12 --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_18.py @@ -0,0 +1,214 @@ +"""Round 18: UNKNOWN priors and the current freeze. + +Verification class: statutory conformance on invented declarations; no +population, behavioral or forecast claim. + +UNKNOWN priors stand for every prior history. 404.130(f) and RS 00301.120 +count all periods or disregard all of them. Counting an added prior can take a +credited quarter from the record, and disregarding it drops the current period +too. Only the disregard speaks for every history, so a reported status or +lower date needs one filling with the reported start that attains it with no +period in force (404.321(a); RS 00301.230; source conflict +us:oasdi-insured-one-filling-first-start). +""" + +from dataclasses import replace +from datetime import date + +import pytest + +from populace_dynamics.track_b import insured_status as i +from tests.test_track_b_insured_status_fix_round_17 import ( + ASSIGNMENT, + LOWER_ANNUAL, + OBSERVED, + UNKNOWN, + _history, + _lower_person, + _person, + _refused_with, + _result, +) + +DISABILITY = i.InsuredTest.DISABILITY +CURRENTLY = i.InsuredTest.CURRENTLY +# The 2000Q1 start needs the QC of 2000 in that quarter, and the 13 quarters +# through 2003Q2 then hold five QCs with no period in force. The freeze lifts +# them, and a prior over 1996 to 1999 takes that lift away. +FREEZE_ANNUAL = { + 1986: 4, + 1987: 4, + 1992: 1, + 1996: 4, + 1997: 4, + 1998: 4, + 1999: 4, + 2000: 1, + 2001: 4, + 2002: 1, +} + + +def _unknown_priors(end=date(2007, 12, 31), **changes): + return _lower_person( + prior_disability_periods_provenance=UNKNOWN, + current_disability_period_end=end, + current_disability_period_end_provenance=OBSERVED, + **changes, + ) + + +def _unknown_ending(through=date(2007, 12, 31)): + return _lower_person( + prior_disability_periods_provenance=UNKNOWN, + current_disability_period_continues_through=through, + current_disability_period_continues_through_provenance=OBSERVED, + ) + + +def _unknown_year(year): + years = _history(1960, 2010, LOWER_ANNUAL) + years[year] = i.CoverageYear(UNKNOWN) + return years + + +# The lower date. + + +@pytest.mark.parametrize( + "person,years", + ( + (_unknown_priors(), _history(1960, 2010, LOWER_ANNUAL)), + (_unknown_ending(), _history(1960, 2010, LOWER_ANNUAL)), + (_unknown_priors(), _unknown_year(2007)), + (_unknown_ending(), _unknown_year(2007)), + ), + ids=("known_end", "unknown_end", "unknown_year", "unknown_end_and_year"), +) +def test_the_freeze_cannot_carry_a_lower_date(person, years): + # A prior over 1999Q2 to 1999Q4 begins fully insured. With the 2000 QC in + # 2000Q1, counting both periods leaves 19 QCs, and disregarding both leaves + # 19 in the quarters through 2010Q1, so 2010-03-31 overstates that history. + _refused_with(ASSIGNMENT, person, years, date(2010, 1, 1), test=DISABILITY) + + +@pytest.mark.parametrize("person", (_unknown_priors(), _unknown_ending())) +def test_a_frozen_exit_cannot_carry_it_either(person): + _refused_with( + ASSIGNMENT, + person, + _history(1960, 2005, LOWER_ANNUAL), + date(2027, 1, 1), + test=DISABILITY, + coverage_end_month=date(2005, 12, 1), + ) + + +def test_a_date_with_no_period_in_force_computes(): + # A fourth 2005 QC gives the quarters through 2010Q1 their 20 with the + # 2000 QC in 2000Q1, so every prior history holds this date. + result = _result( + _unknown_priors(), + _history(1960, 2010, {**LOWER_ANNUAL, 2005: 4}), + date(2010, 1, 1), + test=DISABILITY, + ) + assert result.current_disability_period_start == date(2000, 1, 1) + assert result.dli.lower == date(2010, 3, 31) + + +def test_every_ending_shares_that_date(): + # With no period in force the ending changes nothing. + result = _result( + _unknown_ending(through=date(2000, 1, 1)), + _history(1960, 2010, {**LOWER_ANNUAL, 2005: 4}), + date(2010, 1, 1), + test=DISABILITY, + ) + assert result.dli.lower == date(2010, 3, 31) + + +def test_a_known_history_keeps_the_freeze(): + # An OBSERVED empty history has no added prior to fear, and the current + # period carries the date on the same placements. + result = _result( + _lower_person( + current_disability_period_end=date(2007, 12, 31), + current_disability_period_end_provenance=OBSERVED, + ), + _history(1960, 2010, LOWER_ANNUAL), + date(2010, 1, 1), + test=DISABILITY, + ) + assert result.dli.lower == date(2010, 3, 31) + + +def test_a_fixed_start_needs_no_search_on_unknown_priors(monkeypatch): + def no_search(*args): + raise AssertionError("A fixed start needs no placement search") + + monkeypatch.setattr(i, "_fillings_keeping_start", no_search) + counts = dict.fromkeys(range(1985, 1996), 4) + counts.update(dict.fromkeys(range(1996, 2006), 2)) + result = _result( + _unknown_priors(), + _history(1960, 2010, counts), + date(2010, 1, 1), + test=DISABILITY, + ) + assert result.dli.lower is not None + + +# The statuses. + + +def _freeze_person(**changes): + values = dict( + disability_onset=date(2000, 1, 1), + current_disability_period_established=True, + current_disability_period_end=date(2002, 12, 31), + current_disability_period_end_provenance=OBSERVED, + prior_disability_periods_provenance=UNKNOWN, + ) + values.update(changes) + return replace(_person(**values), birth_date=date(1970, 2, 2)) + + +@pytest.mark.parametrize("test", (i.InsuredTest.ALL, CURRENTLY)) +@pytest.mark.parametrize("unknown_end", (False, True)) +def test_a_status_resting_on_the_freeze_refuses(test, unknown_end): + person = _freeze_person() + if unknown_end: + person = _freeze_person( + current_disability_period_end=None, + current_disability_period_end_provenance=UNKNOWN, + ) + _refused_with( + ASSIGNMENT, + person, + _history(1970, 2003, FREEZE_ANNUAL), + date(2003, 4, 1), + test=test, + ) + + +def test_a_status_with_no_period_in_force_computes(): + result = _result( + _freeze_person(), + _history(1970, 2003, {**FREEZE_ANNUAL, 2002: 2}), + date(2003, 4, 1), + test=CURRENTLY, + ) + assert result.current_disability_period_start == date(2000, 1, 1) + assert result.currently.insured + + +def test_a_known_history_keeps_the_status(): + result = _result( + _freeze_person(prior_disability_periods_provenance=OBSERVED), + _history(1970, 2003, FREEZE_ANNUAL), + date(2003, 4, 1), + test=CURRENTLY, + ) + assert result.current_disability_period_start == date(2000, 1, 1) + assert result.currently.insured diff --git a/tests/test_track_b_insured_status_status_stress.py b/tests/test_track_b_insured_status_status_stress.py index da88ddba2..1d0d0e0ba 100644 --- a/tests/test_track_b_insured_status_status_stress.py +++ b/tests/test_track_b_insured_status_status_stress.py @@ -12,8 +12,9 @@ DIB entitlement month, which ends a CURRENTLY window before the onset. A third draws ages 22-30 at onset, where 404.130(c) applies. A fourth declares a special-insured prior after age 31, where 404.130(d) applies. Declared priors -are not re-adjudicated. No flags, UNKNOWN facts, raw earnings or death are -claimed. +are not re-adjudicated. No flags, raw earnings or death are claimed, and +UNKNOWN facts appear only in ``check_unknown_ending`` and +``check_every_history``. Every annual placement and both all-prior treatments are enumerated. A lawful filling has its own first insured start (404.321(a)), and that start supplies @@ -31,7 +32,7 @@ from itertools import combinations, product import pytest -from hypothesis import example, given, settings +from hypothesis import assume, example, given, settings from hypothesis import strategies as st from populace_dynamics.track_b import insured_status as rule @@ -575,6 +576,163 @@ def check_unknown_ending(case, unknown_prior=False): return "computed" +DISABILITY = rule.InsuredTest.DISABILITY +CURRENTLY = rule.InsuredTest.CURRENTLY +EDGE_ANNUAL = { + 1995: 3, + 1996: 4, + 1997: 4, + 1998: 4, + 1999: 4, + 2000: 1, +} +# The quarters through 2010Q1 hold 20 QCs only with the 2000 QC after 2000Q1, +# and the start holds it there. The current period lifts the date back. +FREEZE_DATE = { + "birth": date(1960, 2, 2), + "onset": date(2000, 1, 1), + "ending": date(2007, 12, 31), + "month": date(2010, 1, 1), + "blind": False, + "prior": (), + "annual": { + **EDGE_ANNUAL, + 2001: 4, + 2002: 4, + 2003: 4, + 2004: 4, + 2005: 3, + }, +} +# The 13 quarters through 2003Q2 hold six QCs only with the 2000 QC after +# 2000Q1. The current period lifts the status back, and a prior over 1996 to +# 1999 takes that lift away. +FREEZE_STATUS = { + "birth": date(1970, 2, 2), + "onset": date(2000, 1, 1), + "ending": date(2002, 12, 31), + "month": date(2003, 4, 1), + "blind": False, + "prior": (), + "annual": { + 1986: 4, + 1987: 4, + 1992: 1, + 1996: 4, + 1997: 4, + 1998: 4, + 1999: 4, + 2000: 1, + 2001: 4, + 2002: 1, + }, +} + + +def added_priors(case): + """Undeclared priors that end before the onset, each past five months.""" + year = case["onset"].year + return tuple( + ((date(year - back, month, 1), date(year - 1, 12, 31)),) + for back, month in ((1, 4), (2, 1), (4, 1)) + ) + + +def prior_can_begin(case, credits, periods): + """404.130(a), (e): even a blind prior begins fully insured.""" + return all( + disability(case["birth"], credits, quarter(begins), (), True) + for begins, _ in periods + ) + + +def history_fillings(case, added, start, ending): + """Fillings with the reported start on a history holding ``added``.""" + return [ + filling + for filling in lawful_fillings( + {**case, "prior": added, "ending": ending} + ) + if filling[0] == start and prior_can_begin(case, filling[7], added) + ] + + +def check_every_history(case, unknown_end=False, test=rule.InsuredTest.ALL): + """No lawful prior history may undercut a computed result. + + UNKNOWN priors stand for each history below, so a filling with the + reported start has to hold each true status and reach the lower date on + it, whichever period ending the record has. + """ + try: + result = public( + {**case, "unknown_end": unknown_end, "unknown_prior": True}, + test=test, + ) + except rule.InsuredConfigurationUnsupported: + return "refused" + except InvalidFamilyInput: + return "invalid" + if result.current_disability_period_start is None: + return "no start" + start = quarter(result.current_disability_period_start) + endings = (case["ending"],) + if unknown_end: + endings = ( + quarter_end(start), + quarter_end(quarter(case["month"])), + date(case["birth"].year + 70, 12, 31), + ) + fully, currently = result.fully, result.currently + lower = None if result.dli is None else result.dli.lower + for added in added_priors(case): + for ending in endings: + held = history_fillings(case, added, start, ending) + if not held: + continue + found = (case, added, ending, result) + assert ( + fully is None + or not fully.insured + or any(filling[1] for filling in held) + ), found + assert ( + currently is None + or not currently.insured + or any(filling[2] for filling in held) + ), found + assert lower is None or quarter(lower) <= max( + -1 if filling[6] is None else filling[6] for filling in held + ), found + return "computed" + + +def start_edge_declaration(seed): + """A record whose start needs the next QC, with its tail redrawn. + + Each draw keeps the QCs that put the start at the edge, and moves the + last QCs, the ending and the query around the record's own boundary. + """ + draw = random.Random(seed) + case = draw.choice((FREEZE_DATE, FREEZE_STATUS)) + annual = dict(case["annual"]) + last = max(annual) + annual[last] = draw.randint(max(annual[last] - 1, 0), 4) + annual[last - 1] = draw.randint(max(annual[last - 1] - 1, 0), 4) + month = date( + case["month"].year + draw.randint(-1, 1), + draw.choice((1, 4, 7, 10)), + 1, + ) + ending = date(case["ending"].year + draw.randint(-1, 0), 12, 31) + return { + **case, + "ending": ending, + "month": month, + "annual": {y: n for y, n in annual.items() if n and y <= month.year}, + } + + @pytest.mark.parametrize("seed", (5000026, 5000168)) def test_status_stress_year_counts_follow_the_returned_filling(seed): # The start's witness leaves a prior's interior holding a year's QCs. @@ -678,3 +836,70 @@ def test_status_stress_unknown_ending_and_prior(seed): {**case, "month": date(case["onset"].year + 2, 1, 1)}, unknown_prior=True, ) + + +@pytest.mark.parametrize("unknown_end", (False, True)) +def test_status_stress_an_added_prior_undercuts_the_freeze(unknown_end): + date_case = check_every_history(FREEZE_DATE, unknown_end, DISABILITY) + status_case = check_every_history(FREEZE_STATUS, unknown_end, CURRENTLY) + assert (date_case, status_case) == ("refused", "refused") + + +def test_status_stress_a_date_with_no_period_in_force_holds_every_history(): + annual = {**FREEZE_DATE["annual"], 2005: 4} + case = {**FREEZE_DATE, "annual": annual} + assert check_every_history(case, test=DISABILITY) == "computed" + + +def test_status_stress_a_status_with_no_period_in_force_holds_every_history(): + annual = {**FREEZE_STATUS["annual"], 2002: 2} + case = {**FREEZE_STATUS, "annual": annual} + assert check_every_history(case, test=CURRENTLY) == "computed" + + +def test_status_stress_the_exact_date_on_that_history(): + # Each of the 16 placements with the 2000Q1 start falls to 2009Q4. + added = ((date(1999, 4, 1), date(1999, 12, 31)),) + held = history_fillings( + FREEZE_DATE, + added, + quarter(FREEZE_DATE["onset"]), + FREEZE_DATE["ending"], + ) + assert len({filling[7] for filling in held}) == 16 + assert {filling[6] for filling in held} == {quarter(date(2009, 12, 31))} + + +def test_status_stress_the_status_on_that_history(): + held = history_fillings( + FREEZE_STATUS, + ((date(1996, 1, 1), date(1999, 12, 31)),), + quarter(FREEZE_STATUS["onset"]), + FREEZE_STATUS["ending"], + ) + assert held + assert not any(filling[2] for filling in held) + + +@settings(max_examples=30, deadline=None, derandomize=True) +@given( + seed=st.integers(0, 2**32 - 1), + unknown_end=st.booleans(), + test=st.sampled_from((rule.InsuredTest.ALL, DISABILITY, CURRENTLY)), +) +def test_status_stress_every_history_at_the_start_edge( + seed, unknown_end, test +): + check_every_history(start_edge_declaration(seed), unknown_end, test) + + +@settings(max_examples=20, deadline=None, derandomize=True) +@given( + seed=st.integers(0, 2**32 - 1), + unknown_end=st.booleans(), + test=st.sampled_from((rule.InsuredTest.ALL, DISABILITY, CURRENTLY)), +) +def test_status_stress_every_history(seed, unknown_end, test): + case = {**declaration(seed), "prior": ()} + assume(sum(1 for _ in placements(case["annual"])) <= 96) + check_every_history(case, unknown_end, test) diff --git a/tests/tier_counts.json b/tests/tier_counts.json index eda27d08a..a7bb05f9a 100644 --- a/tests/tier_counts.json +++ b/tests/tier_counts.json @@ -1,7 +1,7 @@ { "schema_version": 1, "counts": { - "unit": 22103, + "unit": 22127, "artifact": 4271, "integration_psid": 1471, "reproduction_legacy": 520, From bbed6be2f8e20e8b88597e8fbb927f5e0d7fa04f Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Mon, 2 Nov 2026 10:44:00 -0500 Subject: [PATCH 25/46] Hold insured results to every placement a period's start allows Sol's fourteenth review of 129d44bd found that the filling round 18 kept doesn't speak for every prior history. A period begins in an insured quarter, so a prior can force an annual QC into one quarter, and that rules out the filling. Under UNKNOWN priors or UNKNOWN establishment, a status at its reported quarter and the lower date now have to pass on every annual placement with no period in force. A start some placement moves stays open. The same defect reached listed priors, so a prior that placement decides joins the search: one filling keeps it and attains the result, or the row refuses by name. DISABILITY's count joins that search. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 243 ++++- .../track_b/insured_status.py | 472 ++++++++-- tests/README-tiers.md | 4 +- ...est_track_b_insured_status_fix_round_17.py | 9 +- ...est_track_b_insured_status_fix_round_18.py | 34 +- ...est_track_b_insured_status_fix_round_19.py | 889 ++++++++++++++++++ ...test_track_b_insured_status_fix_round_2.py | 1 + ...st_track_b_insured_status_status_stress.py | 514 ++++++++-- tests/tier_counts.json | 2 +- 9 files changed, 1961 insertions(+), 207 deletions(-) create mode 100644 tests/test_track_b_insured_status_fix_round_19.py diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index fd14fb3d1..9fc9ccc5d 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -671,7 +671,7 @@ input. An input error propagates and creates no row. | Earnings require an increment after 2027 | `qc_amount_year_unsupported` | | Query before 1968; blind query before 1973; subsequent-special query before May 1983 | `entitlement_before_1968_unsupported`, `blindness_before_1973_unsupported`, `subsequent_special_before_1983_unsupported` | | A subsequent-special period past 40 counted quarters where half the whole period and 20 of the last 40 give different results | `subsequent_special_long_period_unsupported` | -| More than 4,096 disability-boundary combinations, unresolved ordinary-establishment overlap requiring more than 4,096 credit fillings, a first start that placement or prior treatment can move with no one filling supporting the returned result, or a lower date some ending can't reach on a filling with the reported start, or, under UNKNOWN priors, a status or lower date no such filling attains with no period in force, after fixed overlap and every credit-count proof applicable to the surviving flag classes and foreign-credit declaration | `disability_boundary_assignments_unsupported` | +| More than 4,096 disability-boundary combinations, unresolved ordinary-establishment overlap requiring more than 4,096 credit fillings, a first start that placement or prior treatment can move with no one filling supporting the returned result, a lower date some ending can't reach on a filling with the reported start, a status or lower date some annual placement doesn't attain with no period in force under UNKNOWN priors or UNKNOWN establishment, or a listed prior that annual placement decides where an UNKNOWN year stands open or no filling that keeps the prior attains the result, after fixed overlap and every credit-count proof applicable to the surviving flag classes and foreign-credit declaration | `disability_boundary_assignments_unsupported` | The round-3 observable-trigger audit covers every `CoverageCondition`. An explicit condition continues to refuse under its own reason when the @@ -828,12 +828,12 @@ to a statutory sentence that does not state it. | --- | --- | | U1. UNKNOWN prior history can collapse to empty solely for impossibility validation when no earliest prior period could start insured, on/after birth, before current onset and the FRA end. | C320(b)(2) and C321(a) require an insured beginning without a still-earlier period. A216(i)(2)(A) permits "five full calendar months' duration or" DIB entitlement "for one or more months". The scan therefore admits a one-month period and maximum feasible earnings. Any possible ordinary or specialist starting route stops the proof. It establishes no observed empty-history fact. | | U2. UNKNOWN current establishment needs no new-period alternative if there is no medical onset or onset is at/after the statutory latest starting month. | A216(i)(2)(A)-(D) and C321 prohibit a period without disability or a nonempty pre-FRA interval. This removes an impossible new-period alternative only; it does not remove UNKNOWN prior history or an existing period's UNKNOWN administrative end. | -| U3. With unknown prior/current periods, true ordinary FULLY and CURRENTLY status under favorable all-period disregard decides true. A DISABILITY witness must also survive any current-establishment completion that ends the disability before that witness. With a reported start, one filling with that start must attain the status with no period in force (round 18). | C320(a): "If benefits ... would be denied or reduced because of a period of disability, the period of disability will not be taken into consideration." B404.130(f) also permits counting all prior quarters if favorable. RS .120 requires all periods used or all disregarded; selective exclusions are not assumed. Specialist credit regimes are refused first. | +| U3. With unknown prior/current periods, true ordinary FULLY and CURRENTLY status under favorable all-period disregard decides true. A DISABILITY witness must also survive any current-establishment completion that ends the disability before that witness. Every annual placement must attain the status at the quarter it reports with no period in force, because a period's own start can rule a filling out (round 19). | C320(a): "If benefits ... would be denied or reduced because of a period of disability, the period of disability will not be taken into consideration." B404.130(f) also permits counting all prior quarters if favorable. RS .120 requires all periods used or all disregarded; selective exclusions are not assumed. Specialist credit regimes are refused first. | | U4. With unknown periods, fewer than six maximum QCs feasible by the immutable horizon proves establishment impossible after routes adding undeclared credits are excluded, except for blindness with a fully-route flag; it supplies no foreign-credit impossibility proof. | B404.110(b)(1) and B404.130(a) supply the ordinary six-QC prerequisite. U3's disregard cannot manufacture credits. UNKNOWN prior history disables both I15 and I16; current nonblindness cannot exclude a past blind prior. The separate emptiness proof tests the earliest prior as blind, and proves emptiness only if no earlier quarter can supply fully insured status or the alternate. It can preserve a fully-route refusal with empty recent windows only after the universal six-QC horizon floor clears (I17). Foreign credits, credit-route flags, and raw-earnings flags outside a complete direct envelope also preserve named refusals. The direct-envelope contract and declared pre1956 alternate still obey I9; that alternate flag adds no route beyond B4. Blindness alone supplies no credits and does not replace the ordinary fully insured prerequisite. | | U5. UNKNOWN earnings decide a requested Boolean only if all lower/upper ordinary earnings witnesses agree, under the permitted fixed-period/all-period treatments; an uncertain established start refuses only after at least one feasible filling survives. | B404.143 credits one QC for each increment, maximum four; B404.130 and .146 supply assignment/exclusion rules. Adding ordinary QCs cannot invalidate a fixed treatment. A derived start cannot be silently held fixed when the completion changes it. If a lower or upper representative cannot construct the declared period, but another single filling meets its end, continuity, and prior-overlap constraints, the public result is `unknown_earnings_years_decide_status`. If no ordinary filling can qualify by the declared end and all independent routes are impossible, it is an input error and creates no row. A deferred raw-conversion row uses temporary unknown fillings only for possibility, then retains its conversion refusal. Specialist possibilities and administrative-end candidates are considered separately. | | U6. UNKNOWN administrative end decides a status only when every end-quarter candidate from start through query/cap, plus permitted continuation, agrees, after applying any continuity lower bound. | A216(i)(2)(D) uses "whichever ... is the earlier"; C321(c)(3) includes "the last month for which you received benefits" after substantial gainful activity. Medical continuity cannot exclude early ends; a dated administrative continuity observation can. FRA/death caps limit the latest candidate and do not turn the unknown into a fact. Both ending and prior-history unknown facts remain disclosed when both are missing; UNKNOWN prior history uses the universal envelopes rather than inventing a derived current period to enumerate. The unchanged completion enumeration can include early endings rejected by I14 if declared concretely. Agreement across that larger set still implies agreement across every valid completion, while disagreement can preserve an extra refusal. An actual supplied end keeps its declared-date semantics; known ending provenance requires an ending date. | | U7. UNKNOWN SSPA applicability preserves an ordinary QC-only false status, but never a QC-only true status. | RS .102 B.2 says the worker "must meet one of the following additional requirements" and may fail "even if" the QC requirement is met. Applicability can remove ordinary insurance and cannot supply missing QCs. Known applicability retains adjudication refusal; any separate specialist path is refused first. | -| U8. With UNKNOWN prior history, a known current period's start is certain onset only if the lower-credit favorable-disregard witness already insures at onset; otherwise the start stays unknown. | A216(i)(2)(C) and C321(a) make insured onset the earliest legal start. C320(a)'s disregard permits that witness, and no route can move this period before medical onset. Other potentially valid histories prevent an impossibility error but do not fabricate a start. | +| U8. With UNKNOWN prior history, a known current period's start is certain onset only if the lower credits insure the onset on every annual placement with no period in force (round 19); otherwise the start stays unknown. | A216(i)(2)(C) and C321(a) make insured onset the earliest legal start. C320(a)'s disregard permits that witness, and no route can move this period before medical onset. Other potentially valid histories prevent an impossibility error but do not fabricate a start. | | U9. A continues-through observation removes only candidate administrative ends before its date; it never supplies an ending endpoint or removes UNKNOWN-end disclosure. | C321(c) enumerates actual ending events. Observation of a period still in force supplies a lower bound on those events, not their occurrence. Same-quarter ends remain possible, while a later-quarter observation makes the query quarter interior. | | U10. An automatic alternate-pre1956 possibility can be removed for every filling only when the lower-credit filling has ordinary 20/40 in a quarter disabled in every ending completion, before October 1960. | RS .480 A says "does not have 20/40 for freeze or DIB in any quarter before 10/60". Counts under a fixed all-period use/disregard treatment are monotone in added QCs. The scan retains query, 1960Q3, and month-before-FRA caps for every person (A216(i)(2)(D); C315(a); C321(a)–(b)). For established current periods, its shared date is the declared end minus two calendar months, or continuity date minus two when the end is UNKNOWN, or onset if neither is supplied; it is never before onset. The same two-month exclusion offset applies to FRA/death endings because an earlier recovery remains a possible completion, without inferring that it occurred. UNKNOWN establishment before FRA uses onset. A quarter counts only if its first month is on or before that shared date. RS .480 A's "any quarter" supports a wider scan, while "though under a disability" and "for freeze or DIB" support the shared disabled-quarter scan. A difference preserves the named refusal. Young-worker or blindness witnesses are not substituted for 20/40, upper-only witnesses cannot exclude every filling, and application facts remain unmodeled. | @@ -849,8 +849,8 @@ to a statutory sentence that does not state it. | B6. With known earnings and an UNKNOWN ending, returned count bounds include all end-candidate counts admitted by continuity; with entirely known facts they remain exact. | B404.120(b), .130(f), .146(d) distinguish credited endpoints and excluded interiors. All candidate quarters are enumerated, including early endpoints and capped-FRA candidates, subject to any continues-through observation; extrema therefore cover each completion. A continuity date is never inserted as a credited endpoint. No monotonic endpoint-count premise is used. | | B7. DLI lies through query without frozen exit, or through the pre-FRA-quarter/death horizon with frozen coverage; `None` is the bottom bound. A future exit cannot remove query censoring. | RS .148 defines DLI as "the last day in the last quarter" in which status is met and limits the search relative to FRA. B404.146(b) caps credits after death; A216(i)(2)(B) caps new periods. Future undeclared work is not assumed zero. Specialist routes are refused before this ordinary DLI calculation. | | B8. For a nonblind ordinary worker with no prior period, no DLI can lie more than 39 quarters after the last credited quarter. | B404.130(b)(2) requires "at least 20 QCs in the 40-quarter period ... ending with that quarter". After 39 later quarters no original QC remains. Blindness and prior-period special/exclusion routes disable this search shortcut; flagged or observable specialist routes refuse. | -| B9. With unknown periods the disregard DLI is a lower bound and the permitted query/FRA/death horizon is the upper bound; unknown SSPA applicability reduces any positive DLI lower bound to `None`. | C320(a) permits favorable disregard; B404.130(f) permits counting all prior-period quarters; RS .102 B.2 imposes an additional requirement. The bound does not infer a particular recovery or history. Exemption can recover the ordinary upper witness but cannot exceed the calendar horizon. Round 18 requires one filling with the reported start to reach the lower bound with no period in force, and refuses by name otherwise. | -| B10. UNKNOWN-ending DLI bounds include every end candidate. With an unresolved ongoing end, known prior history, and frozen-exit future horizon beyond query, the named DLI-horizon refusal remains. | C321(c)'s alternative endings and RS .148's last qualifying quarter permit different historical DLI witnesses. The candidate extrema bound all declared endings; no recovery beyond the query is inferred. Refusal covers the unobserved future administrative fact. Round 17 requires every ending to reach the lower date on a filling with the reported start, and refuses by name otherwise. Under UNKNOWN priors that filling reads no period in force, so no ending changes it (round 18). | +| B9. With unknown periods the disregard DLI is a lower bound and the permitted query/FRA/death horizon is the upper bound; unknown SSPA applicability reduces any positive DLI lower bound to `None`. | C320(a) permits favorable disregard; B404.130(f) permits counting all prior-period quarters; RS .102 B.2 imposes an additional requirement. The bound does not infer a particular recovery or history. Exemption can recover the ordinary upper witness but cannot exceed the calendar horizon. Round 19 requires every annual placement to reach the lower bound with no period in force, and refuses by name otherwise. | +| B10. UNKNOWN-ending DLI bounds include every end candidate. With an unresolved ongoing end, known prior history, and frozen-exit future horizon beyond query, the named DLI-horizon refusal remains. | C321(c)'s alternative endings and RS .148's last qualifying quarter permit different historical DLI witnesses. The candidate extrema bound all declared endings; no recovery beyond the query is inferred. Refusal covers the unobserved future administrative fact. Round 17 requires every ending to reach the lower date on a filling with the reported start, and refuses by name otherwise. Under UNKNOWN priors every placement must reach it with no period in force, so no ending changes it (round 19). | | B11. At most 4,096 combinations of disability endpoint assignments are searched exactly, after any applicable impossibility proof. | B404.143(b) and RS .230 permit favorable assignment; B404.130(f) makes credited endpoints decisive. Fixed-overlap, six-QC, and I15's minimum-requirement checks precede `_boundary_variants`, including both alternate-path calls and UNKNOWN-prior-history feasibility. A remaining excess returns `disability_boundary_assignments_unsupported`; computational complexity is neither a statutory impossibility bound nor permission to retain an all-invalid declaration. | | B12. Ordinary counted windows have 13 quarters for current insurance and 40 for ordinary disability; young/subsequent special windows require half their elapsed quarters after dropping an odd remainder, with a six-QC minimum. The young-worker window holds at most 39 quarters. A subsequent-special period past 40 quarters computes only where the Act's whole period and 404.130(d)(2)'s 20 of 40 agree (round 17). | B404.120(a) says "13-quarter period"; .130(b) says "20 QCs in the 40-quarter period"; .130(c)-(d) and A216(i)(3)(B) supply the half-quarter, odd-remainder, and 6/12 alternatives. Blindness uses only the fully insured prerequisite. A fully-route flag must still leave a recent-rule witness or possible automatic pre1956 alternate where I16 applies; the pre1956 flag adds no route beyond that alternate. Specialist paths retaining possibility receive their named refusal. | | B13. Indexed annual QC amounts are at least the prior year's statutory increment and the rounded indexed 1978 amount, with nearest-$10 rounding and $5 ties upward. | A213(d)(2) chooses "the larger of" the prior increment and indexed amount, rounded to "the next higher multiple of $10" at a $5 tie. This exact parameter calculation has no disability or specialist alternative; input-domain checks require positive NAWI and a statutory prior increment. | @@ -1967,7 +1967,7 @@ seeds and generates more. Two more generators add a DIB entitlement month, drawn mostly from partial years up to the onset, and ages 22 to 30 at onset under 404.130(c) and (d). UNKNOWN facts and flags stay outside its claim, and round 16 adds the date last insured and the subsequent-special route. -Declared priors are not re-adjudicated. +Round 19 holds a declared prior's own start (`prior_holds`). After the fix, the same 28,000 and 14,000 fresh declarations give no disagreement, no false rejection and no computed row without a lawful @@ -2224,8 +2224,8 @@ frozen OP12 exit overstates its lower date the same way. `_settle_lower_date` now searches fillings that keep the reported start, and refuses by name unless each ending reaches the lower date. It runs on the lower credits, because a lower date comes from those credits, so an UNKNOWN -year reaches the same check. UNKNOWN priors reach it too, and round 18 holds -them to a filling with no period in force. +year reaches the same check. UNKNOWN priors reach it too, and round 19 holds +them to every placement with no period in force. `_fillings_keeping_start` holds the search that `_settle_first_start` already ran. @@ -2319,15 +2319,14 @@ the 40 quarters through 2010Q1 and 20 through 2009Q4, so that history's exact date is 2009-12-31. A known ending, an UNKNOWN ending, UNKNOWN 2007 credits and a frozen OP12 exit all reported a date past it. -`_fillings_keeping_start` now gives each filling the record with no period in -force under UNKNOWN priors, and `_settle_lower_date` needs one such filling to -keep the start and reach the date. That filling speaks for every history. The -start under UNKNOWN priors is the onset, and the onset's witness stands on any -history that disregards all periods. The same disregard stays open at each -later quarter, so the date holds, whatever the period's ending. Where no -filling reaches the date, the row refuses with -`disability_boundary_assignments_unsupported` and keeps its weight. Lowering -the date instead would also be safe, and the session kept round 17's refusal. +`_fillings_keeping_start` gave each filling the record with no period in force +under UNKNOWN priors, and `_settle_lower_date` needed one such filling to keep +the start and reach the date. This round claimed that filling spoke for every +history. Sol's fourteenth review refuted the claim, because a period's own start +can rule that filling out, and round 19 replaced this check with every +placement. Where no filling reached the date, the row refused with +`disability_boundary_assignments_unsupported` and kept its weight. Lowering the +date instead would also be safe, and the session kept round 17's refusal. The lower date itself needed no change: UNKNOWN priors already left it as the date with no period in force, as B9 states. @@ -2343,10 +2342,10 @@ quarter under the half-the-quarters test, and then the 13 quarters through 2003Q2 hold five QCs. For an April 2003 query, `88a0e7bc` reported CURRENTLY true, because the freeze reaches QCs before 2000. A prior from 1996-01-01 through 1999-12-31 takes all but its endpoint QCs, and no filling with the -2000Q1 start stays currently insured on that history. The shared change covers this -record: a filling now attains a status with no period in force, or the row -refuses by name. An OBSERVED empty history keeps the freeze, and both the status -and the date compute there. +2000Q1 start stays currently insured on that history. The shared change covered +this record: a filling attained a status with no period in force, or the row +refused by name, and round 19 asks that of every placement. An OBSERVED empty +history keeps the freeze, and both the status and the date compute there. ### The Mary Brown capture @@ -2393,21 +2392,209 @@ These tests execute the invariants this round adds: - under UNKNOWN priors, a computed status or lower date holds on every lawful prior history with the reported start (`check_every_history` and its stress tests); -- one filling with the reported start attains it with no period in force, and - otherwise the row refuses by name and keeps its weight +- a result resting on the freeze refuses by name and keeps its weight (`test_the_freeze_cannot_carry_a_lower_date`, `test_a_frozen_exit_cannot_carry_it_either`, `test_a_status_resting_on_the_freeze_refuses`); -- the ending changes nothing under UNKNOWN priors - (`test_every_ending_shares_that_date`); -- a date or status with no period in force computes - (`test_a_date_with_no_period_in_force_computes`, - `test_a_status_with_no_period_in_force_computes`); +- round 19 holds a result to every placement, so a date on one filling refuses + on each ending (`test_a_date_on_one_filling_refuses`, + `test_every_ending_refuses_that_date`); +- a status on every placement computes + (`test_a_status_on_every_placement_computes`); - a known history keeps the freeze (`test_a_known_history_keeps_the_freeze`, `test_a_known_history_keeps_the_status`); - a fixed start needs no placement search (`test_a_fixed_start_needs_no_search_on_unknown_priors`). +## Round 19 a period's own start limits the placements + +Verification class: statutory conformance on invented declarations only. +This correction admits no population, behavioral, payment, or forecast claim. +Sol's fourteenth review of `129d44bd` raised one medium, and it reproduced. The +session then found the same defect on listed priors and under UNKNOWN +establishment. Its first fix for listed priors refused a printed POMS record, +so that fix changed before this round closed. + +### One filling doesn't speak for every history + +A period begins in an insured quarter (404.320(b)(2), 404.321(a)), so a prior +can force an annual QC into one quarter. Disregarding a +period removes its exclusions, and its start still has to stand on the +placement. Round 18 asked for one filling with no period in force, and a +history can rule that filling out. + +An invented person born 1961-02-02 has annual QCs 1991:2, four in each of 1992 +to 1994, 1998:1, four in each of 1999 to 2002 and 2003:3, an established period +from 2000-01-01 through 2000-12-31, and UNKNOWN priors. For a January 2008 +query, `129d44bd` reported a lower date of 2008-03-31. A prior from 1998-01-01 +through 1999-12-31 fits this record: past blindness asks for 15 QCs at 1998Q1, +14 precede 1998, and so the 1998 QC falls in that quarter. All 24 of the 96 +placements that keep the prior leave 19 QCs in the 40 quarters through 2008Q1 +with no period in force, and 15 with both periods, so that history's exact date +is 2007-12-31. + +An invented person born 1965-02-02 has annual QCs 1986:4, 1987:1, 1990:1, +1995:3, four in each of 1996 to 1999, 2000:1, 2001:4 and 2002:1, an established +period from 2000-01-01 through 2002-12-31, and UNKNOWN priors. For an April 2003 +query, `129d44bd` reported CURRENTLY true. A prior from 1990-01-01 through +1999-12-31 asks for six QCs at 1990Q1 and finds five before 1990, so it holds +the 1990 QC there. A 2000Q1 start then holds the 2000 QC there too, and each of +the 64 of 1,024 placements that keep both leaves fewer than six QCs in the 13 +quarters through 2003Q2. + +### Every placement carries a result + +`_every_placement_passes` answers for all placements at one quarter. With no +period in force every window ends at the tested quarter, so placing annual QCs +as early as possible before that quarter's year and as late as possible in it +costs the most from every window at once. That worst filling is itself a +filling, so the answer is exact, and +`test_the_worst_filling_matches_every_placement` holds it to exhaustive +placements. + +Disregarding all periods stays open on any placement (404.130(f), RS 00301.120). +A result that every placement attains with no period in force therefore holds +on every completion, and it needs no search of histories. Under UNKNOWN priors +or UNKNOWN establishment, `_settle_every_history` asks that of each true status +at the quarter it reports and of the lower date. Anything less refuses with +`disability_boundary_assignments_unsupported` and keeps its weight. This +replaces round 18's check. + +`_start_fixed` applies the same test to the start under UNKNOWN priors. A start +some placement moves reports `None` and names `current_disability_period_start` +in `unknown_facts`. DISABILITY reports its first favorable quarter, so it +refuses where that quarter fails on some placement, even when a later quarter +holds on all of them (`test_a_status_stands_at_the_quarter_it_reports`). + +This over-refuses a record no lawful history can move. The session accepted +that cost, because a refusal keeps the row and its weight, and Sol's fix text +asks for the refusal until a universal proof exists. Every placement is that +proof, and it asks more than a tighter search of histories would. + +### UNKNOWN establishment + +UNKNOWN establishment stands for a period no one has placed, so it raises the +same question with no prior at all. An invented person born 1965-02-02 has +annual QCs of four in each of 1990 to 1994, 2000:1, 2001:4 and 2002:1, an onset +of 2000-01-01, and UNKNOWN establishment. `129d44bd` reported CURRENTLY true +for an April 2003 query. Only the 2000 QC in 2000Q1 reaches 20 of 40 in any +quarter through 2003Q2, so a period needs that placement. On it, a period +through 2003-03-31 leaves five QCs in the 13 quarters with no period in force +and one with it. + +`_settle_every_history` covers this case, and it reads no listed period, because +the period no one has placed joins any listed prior in a count. A listed prior +alone therefore can't carry such a result +(`test_unknown_establishment_needs_the_disregard`). + +### Listed priors + +The two records above computed the same wrong results at `129d44bd` with the +prior listed OBSERVED. A listed prior differs from an unknown one in one way: +the record names it, so the search can hold it. + +`_prior_start_binds` asks whether placement decides a prior's own start. A prior +that holds on every placement leaves them all open. One that holds on none rests +on something this record doesn't show, and says nothing about placement. Past +blindness leaves no trace in the record and asks only for fully insured status +(404.130(e)), so an unflagged prior needs that much. A flagged prior's holder +"were only insured under paragraph (c)" (404.130(d)(1)), so that holder passes +a special route and not 404.130(b). A prior that every placement carries past +404.130(b) therefore holds on none. + +Otherwise the prior picks among placements, and the logged first-start reading +applies to its start: one filling of the years that can move that start must +keep it and attain the result, and other years stay flexible for each status. +`_keeps_priors` tests one filling. `_settle_listed_priors` searches when no +current period exists, and `_fillings_keeping_start` holds the same priors when +one does. The result then comes from the best witnesses those fillings allow, +and DISABILITY joins that search, reading the person without the period's own +exclusion. For the 1965-born record with a second 2002 QC, the prior holds the +1990 QC in 1990Q1, and DISABILITY reports 20 QCs where `129d44bd` reported 21. + +The first version of this fix refused whenever placement split a prior. That +refused the record of POMS example 8 +(`test_subsequent_under31_poms_140_examples_7_and_8`), whose result rests on +1993 to 1996 and holds on the placement its prior needs. The search computes it +and reports the 1988 QC in 1988Q1 (`test_a_prior_holds_a_qc_in_its_first_quarter`). + +Three limits remain, and each refuses by name. An UNKNOWN year with a prior that +picks among placements refuses, because lower and upper credits then bound +different placements. A filling must attain every reported status and the date +together, so a result resting on two placements refuses even where each status +alone could stand. The search stops at 4,096 placements. UNKNOWN establishment +skips the search, because a result that passes every placement can't move on +a subset of them (`test_unknown_establishment_leaves_a_split_prior_to_the_proof`). + +### Oracle reach and bounds + +`check_every_history` now adds a January and a July prior in each partial year +before the onset, reads every start where the start stays open, and holds a +filling only where each added prior can begin on it. `prior_edge_declaration` +redraws the two records above near their boundary, and +`test_status_stress_every_open_period` does the same under UNKNOWN establishment. +`check` holds a declared prior through `fillings_keeping_priors`, and each prior +now counts the periods before it or disregards them. + +`check_no_period` is new. It exhausts the placements of a record with no current +period, and requires each status, each exact count and the date last insured to +equal the best the declared priors allow, on both readings of a flagged prior. +`listed_prior_declaration`, `two_prior_declaration` and +`special_prior_declaration` feed it. The oracle imports no production helper, +and it doesn't check DISABILITY's count, which its arithmetic doesn't report. +`test_a_prior_limits_what_a_status_reports` pins that count by hand. + +The wide search drew 250 invented declarations from fresh seeds, 150 from +`prior_edge_declaration` and 100 from `declaration`. Each edge seed ran +`check_every_history` on both ending kinds and three requests and again on an +open period, then ran `check` on its listed and two-prior records and +`check_no_period` on those and a flagged record. Each declared seed ran the same +requests and one listed-prior check, and the search skipped 65 declared seeds +with more than 96 placements. All 2,450 checks held: 1,034 computed, 1,164 +refused by name and 252 raised `InvalidFamilyInput`. + +The first pass of this round's 40 listed mutations +(`scratch/review/round19_mutate.py`) ran through the insured status modules with +no restricted open, and 38 failed a named test. `start_search_skips_prior_years` +and `date_search_drops_binding` survived, and +`test_a_prior_reaches_a_year_the_start_cannot` and +`test_a_listed_prior_holds_every_ending_to_the_date` now kill them. Two stress +tests gained `@example` pins while that pass ran, so its results rest on mixed +test bytes. A rerun at the final bytes writes `round_19_mutations` in a later +commit. + +Against `129d44bd`, 44 of the 162 tests then in the five changed modules fail. +Three tests arrived later and two stress tests gained `@example` pins, and four +of those five fail there. The fifth checks only the arithmetic of an invented +history. + +These tests execute the invariants this round adds: + +- under UNKNOWN priors or UNKNOWN establishment, a computed status or lower date + holds on every annual placement with no period in force, and otherwise the row + refuses by name and keeps its weight (`check_every_history` and its stress + tests, `test_a_prior_can_undercut_the_date`, + `test_a_prior_can_undercut_the_status`, + `test_unknown_establishment_alone_refuses`); +- the worst filling matches exhaustive placements at every tested quarter + (`test_the_worst_filling_matches_every_placement`); +- a start some placement moves stays open, and a start every placement holds + stands (`test_a_start_some_placement_moves_stays_open`, + `test_a_fixed_start_is_the_onset`); +- `_prior_start_binds` answers true only where placement splits the prior or a + later prior rests on an earlier one + (`test_placement_binds_a_prior_only_when_it_splits_them`); +- a computed result on a listed prior is the best the prior allows, for each + status, count and date (`check`, `check_no_period`, and their stress tests); +- a listed prior that placement decides never moves a result it can't reach, and + a result no kept filling attains refuses by name + (`test_a_listed_prior_can_undercut_the_date`, + `test_a_listed_prior_can_undercut_the_status`, + `test_a_listed_prior_binds_without_a_current_period`); +- a flagged prior keeps its route and stays short of 404.130(b) + (`test_a_special_prior_needs_a_quarter_of_its_route`, + `test_a_special_prior_stays_short_of_the_ordinary_rule`). + ## Not in scope No real data, population evaluation, baseline claiming hazard, behavioral diff --git a/src/populace_dynamics/track_b/insured_status.py b/src/populace_dynamics/track_b/insured_status.py index 02bc72fcd..da2d446b8 100644 --- a/src/populace_dynamics/track_b/insured_status.py +++ b/src/populace_dynamics/track_b/insured_status.py @@ -1236,6 +1236,7 @@ def _witness( onset=True, ignore_fully_insured=False, use_periods_only=None, + ordinary_only=False, ): end = _qid(at) best = None @@ -1315,7 +1316,7 @@ def _witness( subsequent = any( p.special_insured for p in person.prior_disability_periods ) - if young or subsequent: + if (young or subsequent) and not ordinary_only: first = max( 1937 * 4, _qid(_attain(person.birth_date, 21)) + 1 ) @@ -1685,31 +1686,123 @@ def _complete_current_period(person, quarter): return completed, start -def _start_fixed(person, credits, start, month, exit_month): - """Whether every annual placement insures the favorable first start. +def _every_placement_passes( + person, credits, at, month, exit_month, kind, **options +): + """Whether every annual placement passes a test at one quarter. - Without prior periods every window is a suffix ending at the tested + With no period in force every window is a suffix ending at the tested quarter. Placing annual QCs as early as possible before that quarter's - year and as late as possible in it is therefore the worst filling. If - even that filling is insured, no filling starts later, and the - favorable start already precedes none. Prior periods retain credited - endpoints, so no single worst filling exists and the caller enumerates. + year and as late as possible in it is therefore the worst filling, for + every window at once. It is also a filling, so the answer is exact. The + caller passes a person with no period listed. """ - if person.prior_disability_periods: - return False rows, _ = _world(person, credits, _qid(month), exit_month, False) worst = dict(credits) for year, (fixed, count, allowed) in rows.items(): if count: vacant = sorted(q for q in allowed if q not in fixed) - chosen = vacant[-count:] if year == start.year else vacant[:count] + chosen = vacant[-count:] if year == at.year else vacant[:count] worst[year] = (tuple(sorted((*fixed, *chosen))), 0) - return _witness(person, worst, start, exit_month, InsuredTest.DISABILITY)[ - 0 - ] + return _witness(person, worst, at, exit_month, kind, **options)[0] -def _start_sensitive_years(person, horizon): +def _start_fixed(person, credits, start, month, exit_month): + """Whether every annual placement insures the favorable first start. + + If even the worst filling is insured, no filling starts later, and the + favorable start already precedes none. Prior periods retain credited + endpoints, so no single worst filling exists and the caller enumerates. + """ + return not person.prior_disability_periods and _every_placement_passes( + person, credits, start, month, exit_month, InsuredTest.DISABILITY + ) + + +def _prior_passes(person, credits, index, exit_month, **options): + """Whether a route insures a listed prior's start, with earlier priors. + + Past blindness leaves no trace in the record and asks only for fully + insured status (404.130(e)), so an unflagged prior needs that much. + """ + period = person.prior_disability_periods[index] + earlier = replace( + person, + statutory_blindness=not period.special_insured, + prior_disability_periods=person.prior_disability_periods[:index], + ) + return _witness( + earlier, + credits, + period.start, + exit_month, + InsuredTest.DISABILITY, + **options, + )[0] + + +def _keeps_priors(person, filling, binding, exit_month): + """Whether one filling lets each binding prior begin where it says. + + A flagged prior's holder "were only insured under paragraph (c)" + (404.130(d)(1)), so that holder passes a special route and not 404.130(b). + """ + return all( + _prior_passes(person, filling, index, exit_month) + and not ( + person.prior_disability_periods[index].special_insured + and _prior_passes( + person, filling, index, exit_month, ordinary_only=True + ) + ) + for index in binding + ) + + +def _prior_start_binds(person, lower, upper, index, month, exit_month): + """Whether annual placement decides a listed prior's own start. + + A period begins in a quarter its holder was insured (404.320(b)(2), + 404.321(a)), so a prior can force an annual QC into one quarter. A prior + that holds on every placement leaves them all open. One that holds on + none rests on something this record doesn't show, and says nothing about + placement. Otherwise it picks among them. Lower credits speak for every + completion of an UNKNOWN year, and upper credits bound them all. ``every`` + drops earlier priors, so a later prior resting on one counts as picking, + and the search that follows then keeps the fillings it holds on. + """ + period = person.prior_disability_periods[index] + flagged = period.special_insured + bare = replace( + person, + statutory_blindness=not flagged, + prior_disability_periods=(), + ) + + def every(**options): + return _every_placement_passes( + bare, + lower, + period.start, + month, + exit_month, + InsuredTest.DISABILITY, + **options, + ) + + def some(**options): + return _prior_passes(person, upper, index, exit_month, **options) + + if not flagged: + return not every() and some() + return ( + some() + and not every(ordinary_only=True) + and not (every() and not some(ordinary_only=True)) + ) + + +def _start_sensitive_years(person, start, horizon): """Years whose annual placement can change a first insured quarter. A year wholly inside every tested window, and untouched by a period, @@ -1720,7 +1813,7 @@ def _start_sensitive_years(person, horizon): CURRENTLY window in that year and want it early, so placement stays enumerated there. """ - onset = _qid(person.disability_onset) + onset = _qid(start) last = _qid(horizon) excluded = sum( _qid(period.end) - _qid(period.start) + 1 @@ -1735,13 +1828,58 @@ def _start_sensitive_years(person, horizon): return {quarter // 4 for quarter in quarters} +def _prior_sensitive_years(person, binding): + """Years whose annual placement can change a binding prior's start.""" + return { + year + for index in binding + for year in _start_sensitive_years( + person, + person.prior_disability_periods[index].start, + person.prior_disability_periods[index].start, + ) + } + + +def _placements(person, credits, sensitive, month, exit_month, rank): + """Each annual placement of the sensitive years, best ``rank`` first.""" + rows, _ = _world(person, credits, _qid(month), exit_month, False) + options = { + year: sorted(_assignment_candidates(*row), key=rank) + for year, row in rows.items() + if year in sensitive and row[1] + } + for index, choices in enumerate(product(*options.values())): + if index == 4096: + _refuse( + InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, + "More than 4096 first-start annual placements", + ) + filling = dict(credits) + filling.update( + (year, (choice, 0)) + for year, choice in zip(options, choices, strict=True) + ) + yield filling + + def _period_outcomes( person, completed, start, credits, month, exit_month, kinds, dated ): - """Statuses, date last insured and witnesses for each ending.""" + """Statuses, date last insured and witnesses for each ending. + + Establishment can't rest on its own exclusion, so DISABILITY reads + ``person`` (see the decisions in ``insured_status``). + """ for option in _current_period_completions(person, completed, start, month): witnesses = tuple( - _decision_witness(option, credits, month, exit_month, kind) + _decision_witness( + person if kind is InsuredTest.DISABILITY else option, + credits, + month, + exit_month, + kind, + ) for kind in kinds ) last = ( @@ -1785,49 +1923,25 @@ def _improves(outcome, returned, last_insured): def _fillings_keeping_start( - person, credits, start, month, exit_month, favored + person, credits, start, month, exit_month, favored, binding ): - """Each annual placement and treatment that keeps the reported start. - - UNKNOWN priors stand for every prior history, and counting an added prior - can take a credited quarter from the record. Only disregarding all periods - speaks for every history (404.130(f), RS00301.120), and that drops the - current period too, whatever its ending. Each filling then reads the - person with no period in force. - """ - every_history = ( - person.prior_disability_periods_provenance - is EarningsProvenance.UNKNOWN - ) + """Each placement and treatment keeping the start and binding priors.""" horizon = _current_period_start_horizon(person, month) witness = set( _witness(person, credits, start, exit_month, InsuredTest.DISABILITY)[4] ) - rows, _ = _world(person, credits, _qid(month), exit_month, False) - sensitive = _start_sensitive_years(person, horizon) - options = { - year: sorted( - _assignment_candidates(*row), - key=lambda choice: ( - len(set(choice) - witness), - len(set(choice) - favored), - choice, - ), - ) - for year, row in rows.items() - if year in sensitive and row[1] - } - for index, choices in enumerate(product(*options.values())): - if index == 4096: - _refuse( - InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, - "More than 4096 first-start annual placements", - ) - filling = dict(credits) - filling.update( - (year, (choice, 0)) - for year, choice in zip(options, choices, strict=True) - ) + sensitive = _start_sensitive_years( + person, person.disability_onset, horizon + ) | _prior_sensitive_years(person, binding) + + def rank(choice): + return len(set(choice) - witness), len(set(choice) - favored), choice + + for filling in _placements( + person, credits, sensitive, month, exit_month, rank + ): + if not _keeps_priors(person, filling, binding, exit_month): + continue for treatment in ( (True, False) if person.prior_disability_periods else (None,) ): @@ -1842,7 +1956,7 @@ def _fillings_keeping_start( except InvalidFamilyInput: continue if own_start == start: - yield filling, person if every_history else completed + yield filling, completed def _settle_first_start( @@ -1858,6 +1972,7 @@ def _settle_first_start( last_insured, reported, favored, + binding, ): """Refuse a result no filling and its own first start can support. @@ -1874,8 +1989,7 @@ def _settle_first_start( attains the result. Ties go to ``favored``, the quarters the excluded world credits, so the returned filling keeps a year's credits where it can. A year that cannot move the start stays flexible, so each status - still places it favorably. Under UNKNOWN priors a filling attains a status - only with no period in force (see ``_fillings_keeping_start``). + still places it favorably. The same limit binds what a status reports. Its favorable count and assignment can rest on a placement that would move the start, so @@ -1884,7 +1998,9 @@ def _settle_first_start( the reported start or the placements run out. It returns the filling that attained the result, with the best witnesses the reported start allows. It returns ``(None, ())`` when any filling keeps the start, or - when ``reported`` is None because unknown facts leave only an envelope. + when ``reported`` is None because unknown years leave only an envelope. + The search holds ``binding`` priors too, so their years count as start + years. """ # Source conflict us:oasdi-insured-one-filling-first-start if _start_fixed(person, credits, start, month, exit_month): @@ -1915,10 +2031,89 @@ def _settle_first_start( "First insured start depends on annual placement " "or prior treatment", ) + return _settle_fillings( + person, + _fillings_keeping_start( + person, credits, start, month, exit_month, favored, binding + ), + start, + month, + exit_month, + kinds, + returned, + dated=dated, + last_insured=last_insured, + reported=reported, + detail="First insured start depends on annual placement " + "or prior treatment", + ) + + +def _settle_listed_priors( + person, + credits, + month, + exit_month, + kinds, + returned, + *, + dated, + last_insured, + reported, + favored, + binding, +): + """Refuse a result no placement keeping the listed priors attains. + + The first-start reading applies to a prior's start with no current period + to date: one filling of the years that can move that start must attain + the result, and other years stay flexible for each status. + """ + # Source conflict us:oasdi-insured-one-filling-first-start + return _settle_fillings( + person, + ( + (filling, person) + for filling in _placements( + person, + credits, + _prior_sensitive_years(person, binding), + month, + exit_month, + lambda choice: (len(set(choice) - favored), choice), + ) + if _keeps_priors(person, filling, binding, exit_month) + ), + None, + month, + exit_month, + kinds, + returned, + dated=dated, + last_insured=last_insured, + reported=reported, + detail="Annual placement decides a listed prior's first insured " + "quarter", + ) + + +def _settle_fillings( + person, + fillings, + start, + month, + exit_month, + kinds, + returned, + *, + dated, + last_insured, + reported, + detail, +): + """Find one filling that attains a result, with its best witnesses.""" joint = kept = None - for filling, completed in _fillings_keeping_start( - person, credits, start, month, exit_month, favored - ): + for filling, completed in fillings: outcomes = tuple( _period_outcomes( person, @@ -1949,31 +2144,25 @@ def _settle_first_start( for entries, insured in zip(kept, returned, strict=True) for entry in entries ): - _refuse( - InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, - "First insured start depends on annual placement " - "or prior treatment", - ) + _refuse(InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, detail) return joint, kept def _settle_lower_date( - person, credits, start, month, exit_month, lowest, favored + person, credits, start, month, exit_month, lowest, favored, binding ): """Refuse a lower date that some period ending cannot reach. Each ending's favorable date can rest on a placement that moves the reported start (404.321(a), RS00301.230). A lower bound speaks for every ending, so each needs a filling that keeps the start and reaches it. - UNKNOWN priors leave one outcome for each filling, the record with no - period in force, and it speaks for every ending and prior history. """ # Source conflict us:oasdi-insured-one-filling-first-start if _start_fixed(person, credits, start, month, exit_month): return reached = None for filling, completed in _fillings_keeping_start( - person, credits, start, month, exit_month, favored + person, credits, start, month, exit_month, favored, binding ): found = tuple( last or date.min @@ -1998,6 +2187,59 @@ def _settle_lower_date( ) +def _settle_every_history(person, credits, month, exit_month, decisions, dli): + """Refuse a result some annual placement doesn't attain. + + UNKNOWN priors stand for every prior history, and UNKNOWN establishment + for a period no one has placed. Each such period must begin in a quarter + its holder was insured (404.320(b)(2), 404.321(a)), and that can force an + annual QC into one quarter, so no placement chosen here speaks for every + completion. Disregarding all periods stays open on any placement + (404.130(f), RS00301.120). A result that every placement attains with no + period in force therefore holds on every completion, and it needs no + search of histories. ``credits`` are the lower credits, which speak for + every completion of an UNKNOWN year. + """ + # Source conflict us:oasdi-insured-one-filling-first-start + bare = replace(person, prior_disability_periods=()) + for kind, decision in decisions.items(): + if ( + decision is not None + and decision.insured + and not _every_placement_passes( + bare, + credits, + decision.qualifying_quarter, + month, + exit_month, + kind, + ) + ): + _refuse( + InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, + f"Annual placement decides {kind.value} " + "across the unknown periods", + ) + if ( + dli is not None + and dli.lower is not None + and not _every_placement_passes( + bare, + credits, + _qdate(_qid(dli.lower)), + month, + exit_month, + InsuredTest.DISABILITY, + onset=False, + ) + ): + _refuse( + InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, + "Annual placement decides the lower date last insured " + "across the unknown periods", + ) + + def _current_period_completions(person, completed, start, month): """Every possible end quarter through query, plus continuation. @@ -2719,14 +2961,15 @@ def insured_status( lo_person = hi_person = person lo_start = hi_start = None if person.current_disability_period_established: - onset_witness = _witness( + # A history can force any placement, so only a start that every + # placement insures speaks for every history. + if _start_fixed( person, lower, person.disability_onset, + month, coverage_end_month, - InsuredTest.DISABILITY, - ) - if onset_witness[0]: + ): lo_start = hi_start = person.disability_onset else: uncertain_current_start = True @@ -2954,8 +3197,27 @@ def insured_status( # false current status cannot prove a positive DLI lower date. lo_date = None dli = _computed(DLIRange, lo_date, hi_date, lo_censored or hi_censored) + if prior_unknown or current_unknown: + _settle_every_history( + person, lower, month, coverage_end_month, decisions, dli + ) + # Every placement attains what the proof above passes, so a prior that + # picks among them can't move it. + binding = tuple( + index + for index in range(len(person.prior_disability_periods)) + if not current_unknown + and _prior_start_binds( + person, lower, upper, index, month, coverage_end_month + ) + ) + if binding and unknown: + _refuse( + InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, + "Annual placement decides a listed prior's first insured quarter", + ) placement = None - if lo_start is not None: + if lo_start is not None or binding: favored_rows, _ = _world( lo_person, upper, @@ -2971,31 +3233,48 @@ def insured_status( ) kinds = tuple( kind - for kind in (InsuredTest.FULLY, InsuredTest.CURRENTLY) + for kind in ( + InsuredTest.FULLY, + InsuredTest.CURRENTLY, + *((InsuredTest.DISABILITY,) if binding else ()), + ) if decisions[kind] is not None ) - placement, settled = _settle_first_start( - person, - upper, - hi_start, - month, - coverage_end_month, - kinds, - tuple(decisions[kind].insured for kind in kinds), - dated=dli is not None and not prior_unknown, - last_insured=( - dli.upper if dli is not None and not prior_unknown else None + search = { + "dated": dli is not None, + "last_insured": dli.upper if dli is not None else None, + "reported": ( + None if unknown else tuple(candidates[kind] for kind in kinds) ), - reported=( - None - if unknown or prior_unknown - else tuple(candidates[kind] for kind in kinds) - ), - favored=favored, + "favored": favored, + "binding": binding, + } + returned = tuple(decisions[kind].insured for kind in kinds) + placement, settled = ( + _settle_first_start( + person, + upper, + hi_start, + month, + coverage_end_month, + kinds, + returned, + **search, + ) + if lo_start is not None + else _settle_listed_priors( + person, + upper, + month, + coverage_end_month, + kinds, + returned, + **search, + ) ) for kind, witnesses in zip(kinds, settled, strict=False): decisions[kind] = _status_decision(witnesses, witnesses) - if dli is not None and dli.lower is not None: + if lo_start is not None and dli is not None and dli.lower is not None: _settle_lower_date( person, lower, @@ -3004,6 +3283,7 @@ def insured_status( coverage_end_month, dli.lower, favored, + binding, ) lo_rows, _ = _world( lo_person, diff --git a/tests/README-tiers.md b/tests/README-tiers.md index 86045728b..456cedcdd 100644 --- a/tests/README-tiers.md +++ b/tests/README-tiers.md @@ -39,9 +39,9 @@ pytest --collect-only -q -m oracle_policyengine | tail -1 | Tier | Tests at HEAD | |---|---:| -| `unit` | 22,127 | +| `unit` | 22,188 | | `artifact` | 4,271 | | `integration_psid` | 1,471 | | `reproduction_legacy` | 520 | | `oracle_policyengine` | 308 | -| **Total** | **28,697** | +| **Total** | **28,758** | diff --git a/tests/test_track_b_insured_status_fix_round_17.py b/tests/test_track_b_insured_status_fix_round_17.py index 9c355d680..0c8ab5b59 100644 --- a/tests/test_track_b_insured_status_fix_round_17.py +++ b/tests/test_track_b_insured_status_fix_round_17.py @@ -613,7 +613,14 @@ def _settle(monkeypatch, fillings, lowest): ), ) i._settle_lower_date( - _lower_person(), {}, date(2000, 1, 1), None, None, lowest, frozenset() + _lower_person(), + {}, + date(2000, 1, 1), + None, + None, + lowest, + frozenset(), + (), ) diff --git a/tests/test_track_b_insured_status_fix_round_18.py b/tests/test_track_b_insured_status_fix_round_18.py index d22011b12..cda4ba65d 100644 --- a/tests/test_track_b_insured_status_fix_round_18.py +++ b/tests/test_track_b_insured_status_fix_round_18.py @@ -7,9 +7,10 @@ count all periods or disregard all of them. Counting an added prior can take a credited quarter from the record, and disregarding it drops the current period too. Only the disregard speaks for every history, so a reported status or -lower date needs one filling with the reported start that attains it with no -period in force (404.321(a); RS 00301.230; source conflict -us:oasdi-insured-one-filling-first-start). +lower date needs a filling that attains it with no period in force (404.321(a); +RS 00301.230; source conflict us:oasdi-insured-one-filling-first-start). Round +19 replaced one such filling with all of them, because a period's own start +can rule a filling out. """ from dataclasses import replace @@ -104,28 +105,27 @@ def test_a_frozen_exit_cannot_carry_it_either(person): ) -def test_a_date_with_no_period_in_force_computes(): +def test_a_date_on_one_filling_refuses(): # A fourth 2005 QC gives the quarters through 2010Q1 their 20 with the - # 2000 QC in 2000Q1, so every prior history holds this date. - result = _result( + # 2000 QC in 2000Q1. A history can move that QC, so the reported quarter + # doesn't hold on every placement. + _refused_with( + ASSIGNMENT, _unknown_priors(), _history(1960, 2010, {**LOWER_ANNUAL, 2005: 4}), date(2010, 1, 1), test=DISABILITY, ) - assert result.current_disability_period_start == date(2000, 1, 1) - assert result.dli.lower == date(2010, 3, 31) -def test_every_ending_shares_that_date(): - # With no period in force the ending changes nothing. - result = _result( +def test_every_ending_refuses_that_date(): + _refused_with( + ASSIGNMENT, _unknown_ending(through=date(2000, 1, 1)), _history(1960, 2010, {**LOWER_ANNUAL, 2005: 4}), date(2010, 1, 1), test=DISABILITY, ) - assert result.dli.lower == date(2010, 3, 31) def test_a_known_history_keeps_the_freeze(): @@ -148,8 +148,7 @@ def no_search(*args): raise AssertionError("A fixed start needs no placement search") monkeypatch.setattr(i, "_fillings_keeping_start", no_search) - counts = dict.fromkeys(range(1985, 1996), 4) - counts.update(dict.fromkeys(range(1996, 2006), 2)) + counts = dict.fromkeys(range(1985, 2010), 3) result = _result( _unknown_priors(), _history(1960, 2010, counts), @@ -192,14 +191,17 @@ def test_a_status_resting_on_the_freeze_refuses(test, unknown_end): ) -def test_a_status_with_no_period_in_force_computes(): +def test_a_status_on_every_placement_computes(): + # A second 2002 QC holds the 13 quarters on every placement, and the 2000 + # QC still moves the start, so that stays open. result = _result( _freeze_person(), _history(1970, 2003, {**FREEZE_ANNUAL, 2002: 2}), date(2003, 4, 1), test=CURRENTLY, ) - assert result.current_disability_period_start == date(2000, 1, 1) + assert result.current_disability_period_start is None + assert "current_disability_period_start" in result.unknown_facts assert result.currently.insured diff --git a/tests/test_track_b_insured_status_fix_round_19.py b/tests/test_track_b_insured_status_fix_round_19.py new file mode 100644 index 000000000..3c32a0ff7 --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_19.py @@ -0,0 +1,889 @@ +"""Round 19: a period's own start limits the placements. + +Verification class: statutory conformance on invented declarations; no +population, behavioral or forecast claim. + +A period begins in a quarter its holder was insured (404.320(b)(2), 404.321(a)), +so a period can force an annual QC into one quarter (RS 00301.230; source +conflict us:oasdi-insured-one-filling-first-start). Past blindness asks only +for fully insured status (404.130(e)), and a special prior's holder "were only +insured under paragraph (c)" (404.130(d)(1)). + +UNKNOWN priors and UNKNOWN establishment stand for periods no one has placed, +so no filling chosen here speaks for every completion. Disregarding all periods +stays open on any placement (404.130(f), RS 00301.120), so a result stands when +every placement attains it with no period in force. A listed prior can stand +on some placements only, so one filling of its years must keep it and attain +the result, or the rule refuses by name. +""" + +from dataclasses import replace +from datetime import date + +import pytest +from hypothesis import assume, given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as i +from tests.test_track_b_insured_status_fix_round_17 import ( + ASSIGNMENT, + OBSERVED, + UNKNOWN, + _history, + _person, + _refused_with, + _result, +) +from tests.test_track_b_insured_status_status_stress import ( + disability, + last_insured, + placements, + quarter, + recent, + requirement, + usable, +) + +ALL = i.InsuredTest.ALL +FULLY = i.InsuredTest.FULLY +CURRENTLY = i.InsuredTest.CURRENTLY +DISABILITY = i.InsuredTest.DISABILITY +START = date(2000, 1, 1) +# Fourteen QCs precede 1998, and a prior beginning 1998Q1 needs 15, so it holds +# the 1998 QC in that quarter. The 40 quarters through 2008Q1 then hold 19. +DATE_BIRTH = date(1961, 2, 2) +DATE_ANNUAL = { + 1991: 2, + 1992: 4, + 1993: 4, + 1994: 4, + 1998: 1, + 1999: 4, + 2000: 4, + 2001: 4, + 2002: 4, + 2003: 3, +} +DATE_PRIOR = i.DisabilityPeriod(date(1998, 1, 1), date(1999, 12, 31)) +# Five QCs precede 1990, and a prior beginning 1990Q1 needs six. With that QC +# out of the 40 quarters through 2000Q1, a 2000Q1 start needs the 2000 QC there, +# and the 13 quarters through 2003Q2 then hold five. +STATUS_BIRTH = date(1965, 2, 2) +STATUS_ANNUAL = { + 1986: 4, + 1987: 1, + 1990: 1, + 1995: 3, + 1996: 4, + 1997: 4, + 1998: 4, + 1999: 4, + 2000: 1, + 2001: 4, + 2002: 1, +} +STATUS_PRIOR = i.DisabilityPeriod(date(1990, 1, 1), date(1999, 12, 31)) +# Only the 2000 QC in 2000Q1 reaches 20 of 40 in any quarter through 2003Q2. +ESTABLISH_ANNUAL = { + 1990: 4, + 1991: 4, + 1992: 4, + 1993: 4, + 1994: 4, + 2000: 1, + 2001: 4, + 2002: 1, +} + + +def _date_person(**changes): + values = dict( + disability_onset=START, + current_disability_period_established=True, + current_disability_period_end=date(2000, 12, 31), + current_disability_period_end_provenance=OBSERVED, + prior_disability_periods_provenance=UNKNOWN, + ) + values.update(changes) + return replace(_person(**values), birth_date=DATE_BIRTH) + + +def _status_person(**changes): + values = dict( + disability_onset=START, + current_disability_period_established=True, + current_disability_period_end=date(2002, 12, 31), + current_disability_period_end_provenance=OBSERVED, + current_disability_period_continues_through=START, + current_disability_period_continues_through_provenance=OBSERVED, + prior_disability_periods_provenance=UNKNOWN, + ) + values.update(changes) + return replace(_person(**values), birth_date=STATUS_BIRTH) + + +UNKNOWN_END = dict( + current_disability_period_end=None, + current_disability_period_end_provenance=UNKNOWN, + current_disability_period_continues_through=date(2000, 12, 31), + current_disability_period_continues_through_provenance=OBSERVED, +) +UNKNOWN_ESTABLISHMENT = dict( + current_disability_period_established=None, + current_disability_period_provenance=UNKNOWN, + current_disability_period_end=None, + current_disability_period_end_provenance=UNKNOWN, +) + + +def _unknown_year(years, year): + return {**years, year: i.CoverageYear(UNKNOWN)} + + +# UNKNOWN priors: the date. + + +def test_that_prior_holds_the_date_at_2007q4(): + prior = (DATE_PRIOR.start, DATE_PRIOR.end) + current = (START, date(2000, 12, 31)) + at = quarter(date(2008, 1, 1)) + held = [ + credits + for credits in placements(DATE_ANNUAL) + if disability(DATE_BIRTH, credits, quarter(prior[0]), (), True) + ] + assert len(held) == 24 + for credits in held: + assert disability(DATE_BIRTH, credits, quarter(START), (), False) + use = usable(credits, at, (prior, current)) + assert recent(usable(credits, at, ()), at, (), 40) == 19 + assert recent(use, at, (prior, current), 40) == 15 + best = max( + last_insured(DATE_BIRTH, credits, at, periods, False, False, None) + for periods in ((), (prior, current)) + ) + assert best == 2007 * 4 + 3 + + +@pytest.mark.parametrize( + "changes,unknown_year", + ( + ({}, None), + (dict(disability_onset=date(2000, 1, 15)), None), + (UNKNOWN_END, None), + ({}, 2004), + (UNKNOWN_END, 2004), + (UNKNOWN_ESTABLISHMENT, None), + (UNKNOWN_ESTABLISHMENT, 2004), + ), + ids=( + "known_end", + "onset_day_15", + "unknown_end", + "unknown_year", + "unknown_end_and_year", + "unknown_establishment", + "unknown_establishment_and_year", + ), +) +def test_a_prior_can_undercut_the_date(changes, unknown_year): + years = _history(1961, 2008, DATE_ANNUAL) + if unknown_year is not None: + years = _unknown_year(years, unknown_year) + _refused_with( + ASSIGNMENT, + _date_person(**changes), + years, + date(2008, 1, 1), + test=DISABILITY, + ) + + +@pytest.mark.parametrize( + "changes", ({}, UNKNOWN_END), ids=("known", "unknown") +) +def test_a_frozen_exit_keeps_the_same_refusal(changes): + _refused_with( + ASSIGNMENT, + _date_person(**changes), + _history(1961, 2003, DATE_ANNUAL), + date(2027, 1, 1), + test=DISABILITY, + coverage_end_month=date(2003, 12, 1), + ) + + +def test_a_date_on_every_placement_computes(): + # Four 1998 QCs leave 22 of the 40 quarters through 2008Q1 on every + # placement. + result = _result( + _date_person(), + _history(1961, 2008, {**DATE_ANNUAL, 1998: 4}), + date(2008, 1, 1), + test=DISABILITY, + ) + assert result.current_disability_period_start == START + assert result.dli.lower == date(2008, 3, 31) + + +# UNKNOWN priors: the statuses. + + +def test_that_prior_denies_the_status(): + prior = (STATUS_PRIOR.start, STATUS_PRIOR.end) + current = (START, date(2002, 12, 31)) + at = quarter(date(2003, 4, 1)) + held = [ + credits + for credits in placements(STATUS_ANNUAL) + if disability(STATUS_BIRTH, credits, quarter(prior[0]), (), True) + and disability(STATUS_BIRTH, credits, quarter(START), (), False) + ] + assert len(held) == 64 + for credits in held: + for periods in ((), (prior, current)): + use = usable(credits, at, periods) + assert recent(use, at, periods, 13) < 6 + + +@pytest.mark.parametrize("test", (ALL, CURRENTLY)) +@pytest.mark.parametrize( + "changes", + ({}, dict(disability_onset=date(2000, 1, 15))), + ids=("first_day", "day_15"), +) +def test_a_prior_can_undercut_the_status(test, changes): + if "disability_onset" in changes: + changes = { + **changes, + "current_disability_period_continues_through": changes[ + "disability_onset" + ], + } + _refused_with( + ASSIGNMENT, + _status_person(**changes), + _history(1965, 2003, STATUS_ANNUAL), + date(2003, 4, 1), + test=test, + ) + + +def test_a_frozen_exit_reaches_the_status(): + _refused_with( + ASSIGNMENT, + _status_person(), + _history(1965, 2003, STATUS_ANNUAL), + date(2003, 4, 1), + test=CURRENTLY, + coverage_end_month=date(2003, 4, 1), + ) + + +def test_a_status_on_every_placement_computes(): + result = _result( + _status_person(), + _history(1965, 2003, {**STATUS_ANNUAL, 2000: 2}), + date(2003, 4, 1), + test=CURRENTLY, + ) + assert result.current_disability_period_start is None + assert result.currently.insured + + +# The start. + +START_EDGE = { + 1995: 3, + **dict.fromkeys(range(1996, 2000), 4), + 2000: 1, + **dict.fromkeys(range(2001, 2008), 4), +} + + +@pytest.mark.parametrize("test", (FULLY, CURRENTLY)) +def test_a_start_some_placement_moves_stays_open(test): + # The 2000 QC reaches 20 of 40 in 2000Q1 only there, and the 1995 QCs can + # fall past the back edge. Every placement still holds the status. + result = _result( + _date_person(), + _history(1961, 2008, START_EDGE), + date(2008, 1, 1), + test=test, + ) + assert result.current_disability_period_start is None + assert "current_disability_period_start" in result.unknown_facts + + +def test_a_status_stands_at_the_quarter_it_reports(): + # Every placement reaches 20 of 40 by 2001Q4. The result reports 2000Q1, + # the first favorable quarter, and only some placements hold that one. + _refused_with( + ASSIGNMENT, + _date_person(), + _history(1961, 2002, START_EDGE), + date(2002, 1, 1), + test=DISABILITY, + ) + + +def test_a_fixed_start_is_the_onset(): + result = _result( + _date_person(), + _history(1961, 2008, dict.fromkeys(range(1985, 2008), 4)), + date(2008, 1, 1), + ) + assert result.current_disability_period_start == START + assert "current_disability_period_start" not in result.unknown_facts + + +# UNKNOWN establishment, with no prior. + + +def _open_person(**changes): + values = dict( + disability_onset=START, + prior_disability_periods_provenance=OBSERVED, + **{ + key: value + for key, value in UNKNOWN_ESTABLISHMENT.items() + if key not in changes + }, + ) + values.update(changes) + return replace(_person(**values), birth_date=STATUS_BIRTH) + + +def test_a_period_on_that_record_holds_the_qc_at_2000q1(): + at = quarter(date(2003, 4, 1)) + horizon = range(quarter(START), at + 1) + held = [ + credits + for credits in placements(ESTABLISH_ANNUAL) + if any( + disability(STATUS_BIRTH, credits, candidate, (), False) + for candidate in horizon + ) + ] + assert held + for credits in held: + assert 2000 * 4 in credits + assert recent(usable(credits, at, ()), at, (), 13) == 5 + assert any( + recent(usable(credits, at, ()), at, (), 13) == 6 + for credits in placements(ESTABLISH_ANNUAL) + ) + + +@pytest.mark.parametrize("test", (ALL, CURRENTLY)) +def test_unknown_establishment_alone_refuses(test): + _refused_with( + ASSIGNMENT, + _open_person(), + _history(1965, 2003, ESTABLISH_ANNUAL), + date(2003, 4, 1), + test=test, + ) + + +def test_a_known_absence_keeps_the_status(): + # With no period declared, nothing holds the 2000 QC in 2000Q1. + result = _result( + _open_person( + current_disability_period_established=False, + current_disability_period_provenance=OBSERVED, + current_disability_period_end=None, + current_disability_period_end_provenance=UNKNOWN, + ), + _history(1965, 2003, ESTABLISH_ANNUAL), + date(2003, 4, 1), + test=CURRENTLY, + ) + assert result.currently.insured + + +def test_unknown_establishment_needs_the_disregard(): + # Counting the listed prior reaches back through 1995 for seven of 13, and + # the disregard finds three. A period on this record joins that prior in + # any count, so the listed prior alone can't carry the status. + annual = { + 1995: 4, + 1996: 2, + 2000: 1, + 2001: 1, + 2002: 1, + 2003: 1, + 2004: 1, + } + prior = i.DisabilityPeriod(date(1997, 1, 1), date(2003, 12, 31)) + _refused_with( + ASSIGNMENT, + _open_person( + disability_onset=date(2004, 6, 15), + prior_disability_periods=(prior,), + ), + _history(1965, 2005, annual), + date(2005, 1, 1), + test=CURRENTLY, + ) + + +def test_unknown_establishment_leaves_a_split_prior_to_the_proof(): + # The 1998 QC splits the listed prior, and every placement attains this + # result with no period in force, so the prior can't move it. + annual = {**DATE_ANNUAL, **dict.fromkeys(range(2004, 2008), 4)} + result = _result( + _date_person( + **UNKNOWN_ESTABLISHMENT, + prior_disability_periods=(DATE_PRIOR,), + prior_disability_periods_provenance=OBSERVED, + ), + _history(1961, 2008, annual), + date(2008, 1, 1), + ) + assert result.dli.lower == date(2008, 3, 31) + + +# Listed priors. + + +def test_a_listed_prior_can_undercut_the_date(): + _refused_with( + ASSIGNMENT, + _date_person( + prior_disability_periods=(DATE_PRIOR,), + prior_disability_periods_provenance=OBSERVED, + ), + _history(1961, 2008, DATE_ANNUAL), + date(2008, 1, 1), + test=DISABILITY, + ) + + +def test_a_listed_prior_can_undercut_the_status(): + _refused_with( + ASSIGNMENT, + _status_person( + prior_disability_periods=(STATUS_PRIOR,), + prior_disability_periods_provenance=OBSERVED, + ), + _history(1965, 2003, STATUS_ANNUAL), + date(2003, 4, 1), + test=CURRENTLY, + ) + + +def test_a_listed_prior_binds_without_a_current_period(): + _refused_with( + ASSIGNMENT, + _date_person( + current_disability_period_established=False, + current_disability_period_end=None, + current_disability_period_end_provenance=UNKNOWN, + prior_disability_periods=(DATE_PRIOR,), + prior_disability_periods_provenance=OBSERVED, + ), + _history(1961, 2008, DATE_ANNUAL), + date(2008, 1, 1), + test=DISABILITY, + ) + + +def test_a_prior_limits_what_a_status_reports(): + # The prior holds the 1990 QC in 1990Q1. The 40 quarters through 2000Q1 + # then hold 1995's three, 16 more through 1999 and the 2000 QC, so 20 and + # not the 21 that a later 1990 QC would give. + result = _result( + _status_person( + prior_disability_periods=(STATUS_PRIOR,), + prior_disability_periods_provenance=OBSERVED, + ), + _history(1965, 2003, {**STATUS_ANNUAL, 2002: 2}), + date(2003, 4, 1), + ) + assert result.current_disability_period_start == START + assert result.assigned_quarters[1990] == (1990 * 4,) + assert result.disability.qc_count_lower == 20 + + +def test_a_prior_holds_a_qc_in_its_first_quarter(): + # Six of 12 through 1988Q1 need the 1988 QC in that quarter. The result + # rests on 1993 to 1996, so that placement costs it nothing. + prior = i.DisabilityPeriod( + date(1988, 2, 16), date(1990, 12, 31), special_insured=True + ) + annual = {1986: 1, 1987: 4, 1988: 1, 1993: 2, 1994: 3, 1995: 4, 1996: 3} + result = _result( + replace( + _person(prior, disability_onset=date(1997, 3, 16)), + birth_date=date(1967, 4, 12), + ), + _history(1967, 1997, annual), + date(1997, 3, 1), + ) + assert result.assigned_quarters[1988] == (1988 * 4,) + assert result.disability.insured + assert result.disability.qc_count_lower == 12 + + +def test_a_prior_reaches_a_year_the_start_cannot(): + # The 12 quarters through 1988Q1 hold six only with the 1985 QC after + # 1985Q1, and the 13 through the entitlement month hold six only with it + # there. Only the flagged prior brings 1985 into the first-start search. + prior = i.DisabilityPeriod( + date(1988, 1, 15), date(1990, 12, 31), special_insured=True + ) + annual = { + 1983: 2, + 1984: 3, + 1985: 1, + 1986: 1, + 1987: 4, + **dict.fromkeys(range(1991, 2003), 4), + } + _refused_with( + ASSIGNMENT, + replace( + _person( + prior, + disability_onset=date(2000, 1, 15), + current_disability_period_established=True, + current_disability_period_end=date(2002, 12, 31), + current_disability_period_end_provenance=OBSERVED, + dib_entitlement_month=date(1985, 1, 1), + ), + birth_date=date(1965, 2, 2), + ), + _history(1965, 2003, annual), + date(2003, 4, 1), + test=CURRENTLY, + ) + + +# 26 elapsed years ask for 26 QCs at 1998Q1, and 25 precede 1998, so the +# prior holds the 1998 QC in that quarter. A long ending's freeze reaches the +# 1990s, and the shortest leaves 18 or 19 QCs at 2008Q1 either way. +EVERY_ENDING_BIRTH = date(1950, 2, 2) +EVERY_ENDING_ANNUAL = { + **dict.fromkeys(range(1991, 1997), 4), + 1997: 1, + 1998: 1, + **dict.fromkeys(range(1999, 2003), 4), + 2003: 3, +} + + +def test_the_shortest_ending_misses_2008q1_on_that_prior(): + prior = (DATE_PRIOR.start, DATE_PRIOR.end) + short = (START, date(2000, 12, 31)) + at = quarter(date(2008, 1, 1)) + held = [ + credits + for credits in placements(EVERY_ENDING_ANNUAL) + if disability(EVERY_ENDING_BIRTH, credits, quarter(prior[0]), (), True) + ] + assert len(held) == 16 + for credits in held: + assert 1998 * 4 in credits + for periods in ((), (prior, short)): + assert recent(usable(credits, at, periods), at, periods, 40) < 20 + + +def test_a_listed_prior_holds_every_ending_to_the_date(): + # Every ending keeps the onset start, and the lower date has to hold on + # the fillings the prior allows for each of them. + _refused_with( + ASSIGNMENT, + replace( + _person( + DATE_PRIOR, + disability_onset=START, + current_disability_period_established=True, + current_disability_period_end=None, + current_disability_period_end_provenance=UNKNOWN, + current_disability_period_continues_through=date(2000, 12, 31), + current_disability_period_continues_through_provenance=( + OBSERVED + ), + ), + birth_date=EVERY_ENDING_BIRTH, + ), + _history(1950, 2008, EVERY_ENDING_ANNUAL), + date(2008, 1, 1), + test=DISABILITY, + ) + + +def test_a_prior_every_placement_supports_binds_nothing(): + # By 1999Q1 the 1998 QC has fallen on every placement, and 16 QCs meet the + # 16 required, so the prior leaves the 1998 QC free. + prior = i.DisabilityPeriod(date(1999, 1, 1), date(1999, 12, 31)) + result = _result( + _date_person( + prior_disability_periods=(prior,), + prior_disability_periods_provenance=OBSERVED, + ), + _history(1961, 2008, DATE_ANNUAL), + date(2008, 1, 1), + test=DISABILITY, + ) + assert result.dli.upper == date(2008, 3, 31) + + +def test_a_prior_no_placement_supports_stands_as_declared(): + # Nine QCs are required at 1992Q1 and three can fall by then. The record + # doesn't show what insured that start, so it says nothing about placement. + prior = i.DisabilityPeriod(date(1992, 1, 1), date(1992, 12, 31)) + result = _result( + _date_person( + prior_disability_periods=(prior,), + prior_disability_periods_provenance=OBSERVED, + ), + _history(1961, 2008, DATE_ANNUAL), + date(2008, 1, 1), + test=DISABILITY, + ) + assert result.disability.insured + + +def test_a_later_prior_can_rest_on_an_earlier_one(): + # 14 QCs fall by 1998Q1 on every placement, and only counting the 1995 + # prior brings the requirement down to them. The filling then leaves the + # start to the QCs of 2000: 14 and the 1999 four miss 20 at 2000Q1. + earlier = i.DisabilityPeriod(date(1995, 1, 1), date(1995, 12, 31)) + annual = {year: n for year, n in DATE_ANNUAL.items() if year != 1998} + result = _result( + _date_person( + prior_disability_periods=(earlier, DATE_PRIOR), + prior_disability_periods_provenance=OBSERVED, + ), + _history(1961, 2008, annual), + date(2008, 1, 1), + test=DISABILITY, + ) + assert result.current_disability_period_start == date(2000, 4, 1) + assert result.disability.insured + + +def test_a_later_prior_counts_the_earlier_one_on_every_filling(): + # Counting the 1995 prior lowers the 1998Q1 requirement to 14, which every + # placement meets, so the 1998 QC stays free. The worst filling reads no + # period in force and asks for 15, and that alone would refuse. + earlier = i.DisabilityPeriod(date(1995, 1, 1), date(1995, 12, 31)) + result = _result( + _date_person( + prior_disability_periods=(earlier, DATE_PRIOR), + prior_disability_periods_provenance=OBSERVED, + ), + _history(1961, 2008, DATE_ANNUAL), + date(2008, 1, 1), + test=DISABILITY, + ) + assert result.dli.upper == date(2008, 3, 31) + + +@pytest.mark.parametrize( + "annual", + ( + DATE_ANNUAL, + {year: n for year, n in DATE_ANNUAL.items() if year != 1998}, + ), + ids=("every_needs_lower_credits", "some_needs_upper_credits"), +) +def test_an_unknown_year_reaches_a_listed_prior(annual): + # UNKNOWN 1997 credits run from none, where no placement or only some pass + # 1998Q1, to four, where all do. + _refused_with( + ASSIGNMENT, + _date_person( + current_disability_period_established=False, + current_disability_period_end=None, + current_disability_period_end_provenance=UNKNOWN, + prior_disability_periods=(DATE_PRIOR,), + prior_disability_periods_provenance=OBSERVED, + ), + _unknown_year(_history(1961, 2008, annual), 1997), + date(2008, 1, 1), + test=FULLY, + ) + + +# A listed special prior. + +SPECIAL_START = date(1990, 4, 1) +SPECIAL_BASE = dict.fromkeys(range(1985, 1990), 4) +SPECIAL_BASE[1985] = 2 + + +def _special_person(): + prior = i.DisabilityPeriod( + SPECIAL_START, date(1991, 12, 31), special_insured=True + ) + return _person(prior, disability_onset=None) + + +def test_a_special_prior_needs_a_quarter_of_its_route(): + # Eighteen of 37 elapsed quarters are required. One QC below that, a 1990 + # QC has to fall by 1990Q2. + result = _result( + _special_person(), + _history(1960, 1995, {**SPECIAL_BASE, 1985: 1, 1990: 2}), + date(1995, 1, 1), + ) + assert result.assigned_quarters[1990][0] <= 1990 * 4 + 1 + + +def test_a_special_prior_stays_short_of_the_ordinary_rule(): + # Eighteen QCs pass the route on every placement, and two more in the + # first quarters of 1990 reach 20 of 40. 404.130(d)(1) asks for a holder + # "only insured" under paragraph (c), so one 1990 QC falls after 1990Q2. + result = _result( + _special_person(), + _history(1960, 1995, {**SPECIAL_BASE, 1990: 2}), + date(1995, 1, 1), + ) + held = [q for q in result.assigned_quarters[1990] if q <= 1990 * 4 + 1] + assert len(held) == 1 + + +def test_a_special_prior_on_every_placement_binds_nothing(): + # One 1990 QC can't reach 20 of 40, and 18 pass the route on every + # placement. + result = _result( + _special_person(), + _history(1960, 1995, {**SPECIAL_BASE, 1990: 1}), + date(1995, 1, 1), + ) + assert result.fully.insured + + +def test_a_special_prior_no_placement_supports_stands_as_declared(): + # Twenty QCs reach 20 of 40 on every placement, so the holder was never + # "only insured" under paragraph (c). + result = _result( + _special_person(), + _history(1960, 1995, {**SPECIAL_BASE, 1985: 4}), + date(1995, 1, 1), + ) + assert result.fully.insured + + +def test_a_special_prior_short_of_its_route_stands_as_declared(): + # Seventeen QCs miss the 18 required on every placement. + result = _result( + _special_person(), + _history(1960, 1995, {**SPECIAL_BASE, 1985: 1}), + date(1995, 1, 1), + ) + assert result.fully.insured + + +# The worst filling. + + +def _credits(annual): + return { + year: i._credits(year, i.CoverageYear(OBSERVED, qc_count=count), False) + for year, count in annual.items() + } + + +YEARS = st.integers(1985, 2004) +ANNUAL = st.builds( + lambda full, partial: {**dict.fromkeys(full, 4), **partial}, + st.sets(YEARS, min_size=3, max_size=14), + st.dictionaries(YEARS, st.integers(1, 3), max_size=3), +) + + +@settings(max_examples=150, deadline=None, derandomize=True) +@given( + annual=ANNUAL, + back=st.integers(0, 80), + blind=st.booleans(), + birth_year=st.integers(1945, 1975), +) +def test_the_worst_filling_matches_every_placement( + annual, back, blind, birth_year +): + birth = date(birth_year, 2, 2) + at = 2004 * 4 + 3 - back + assume(at >= (birth_year + 22) * 4) + day = date(at // 4, 3 * (at % 4) + 1, 1) + person = i.Person( + birth, + sex=i.Sex.FEMALE, + statutory_blindness=blind, + prior_disability_periods_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + month = date(2005, 1, 1) + every = { + FULLY: all( + len(usable(c, at, ())) >= requirement(birth, at // 4, ()) + for c in placements(annual) + ), + CURRENTLY: all( + recent(usable(c, at, ()), at, (), 13) >= 6 + for c in placements(annual) + ), + DISABILITY: all( + disability(birth, c, at, (), blind) for c in placements(annual) + ), + } + for kind, expected in every.items(): + assert ( + i._every_placement_passes( + person, _credits(annual), day, month, None, kind + ) + is expected + ), (annual, day, kind) + + +def _lawful_prior(birth, credits, begins, special): + at = quarter(begins) + if not special: + return disability(birth, credits, at, (), True) + return ( + disability(birth, credits, at, (), False) + and recent(usable(credits, at, ()), at, (), 40) < 20 + ) + + +@settings(max_examples=150, deadline=None, derandomize=True) +@given( + annual=ANNUAL, + begins_year=st.integers(1986, 1995), + begins_quarter=st.integers(0, 3), + special=st.booleans(), +) +def test_placement_binds_a_prior_only_when_it_splits_them( + annual, begins_year, begins_quarter, special +): + birth = date(1960, 2, 2) + begins = date(begins_year, 3 * begins_quarter + 1, 1) + assume(not special or begins < date(1991, 2, 2)) + prior = i.DisabilityPeriod( + begins, date(begins_year, 12, 31), special_insured=special + ) + person = i.Person( + birth, + sex=i.Sex.FEMALE, + prior_disability_periods=(prior,), + prior_disability_periods_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + held = { + _lawful_prior(birth, credits, begins, special) + for credits in placements(annual) + } + credits = _credits(annual) + binds = i._prior_start_binds( + person, credits, credits, 0, date(2005, 1, 1), None + ) + if not special: + assert binds is (len(held) == 2), (annual, begins) + elif not binds: + assert len(held) == 1, (annual, begins) diff --git a/tests/test_track_b_insured_status_fix_round_2.py b/tests/test_track_b_insured_status_fix_round_2.py index d81e1720b..de564fd55 100644 --- a/tests/test_track_b_insured_status_fix_round_2.py +++ b/tests/test_track_b_insured_status_fix_round_2.py @@ -385,6 +385,7 @@ def test_unknown_period_status_and_dli_bounds_contain_concrete_fillings( assert error.reason in ( i.InsuredUnsupportedReason.UNKNOWN_PERIODS, i.InsuredUnsupportedReason.UNKNOWN_CURRENT_PERIOD, + i.InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, ) return assert bounded.decided_despite_unknowns diff --git a/tests/test_track_b_insured_status_status_stress.py b/tests/test_track_b_insured_status_status_stress.py index 1d0d0e0ba..f36109bbc 100644 --- a/tests/test_track_b_insured_status_status_stress.py +++ b/tests/test_track_b_insured_status_status_stress.py @@ -11,10 +11,10 @@ blindness in a quarter of cases all vary by seed. A second generator adds a DIB entitlement month, which ends a CURRENTLY window before the onset. A third draws ages 22-30 at onset, where 404.130(c) applies. A fourth declares a -special-insured prior after age 31, where 404.130(d) applies. Declared priors -are not re-adjudicated. No flags, raw earnings or death are claimed, and -UNKNOWN facts appear only in ``check_unknown_ending`` and -``check_every_history``. +special-insured prior after age 31, where 404.130(d) applies. A declared prior +limits the fillings only through its own start (``prior_holds``). No flags, raw +earnings or death are claimed, and UNKNOWN facts appear only in +``check_unknown_ending`` and ``check_every_history``. Every annual placement and both all-prior treatments are enumerated. A lawful filling has its own first insured start (404.321(a)), and that start supplies @@ -24,6 +24,8 @@ the reported start. Each exact count, assignment and date last insured must also be the best a filling with that start attains. A rejection needs no lawful filling. A named refusal retains the declaration and passes. +``check_no_period`` asks the same of a record with no current period, where a +listed prior alone limits the fillings. """ import calendar @@ -164,12 +166,13 @@ def placements(annual): yield frozenset(credit for piece in pieces for credit in piece) -def lawful_fillings(case, reading=LAST_40): +def lawful_fillings(case, reading=LAST_40, *, keep=None, dated=True): """Exhaust every filling before comparing to a public result. Each lawful filling gives its first start, three statuses, the best (insured, margin, count) for FULLY and CURRENTLY, its date last insured - quarter and its credits. + quarter and its credits. ``keep`` limits the placements, and ``dated`` + skips the date for a query that doesn't ask for one. """ birth, onset, ending, month = ( case["birth"], @@ -185,12 +188,17 @@ def lawful_fillings(case, reading=LAST_40): ] or [month] found = [] for credits in placements(annual): + if keep is not None and not keep(credits): + continue for use_prior in (True, False) if prior else (False,): used = prior if use_prior else () first = next( ( candidate - for candidate in range(quarter(onset), quarter(ending) + 1) + for candidate in range( + quarter(onset), + quarter(case.get("through", ending)) + 1, + ) if disability( birth, credits, @@ -230,24 +238,25 @@ def lawful_fillings(case, reading=LAST_40): currently_best = max( currently_best, (held >= 6, held - 6, held) ) - latest = max( - filter( - None, - ( - latest, - last_insured( - birth, - credits, - at, - periods, - blind, - special, - reading, + if dated: + latest = max( + filter( + None, + ( + latest, + last_insured( + birth, + credits, + at, + periods, + blind, + special, + reading, + ), ), ), - ), - default=None, - ) + default=None, + ) found.append( ( first, @@ -278,19 +287,31 @@ def public(case, **options): observed = rule.EarningsProvenance.OBSERVED unknown_end = case.get("unknown_end", False) unknown_prior = case.get("unknown_prior", False) + open_period = case.get("open_period", False) + no_period = case.get("no_period", False) + unknown_end = unknown_end or open_period or no_period + through = case.get("through") person = rule.Person( case["birth"], sex=rule.Sex.FEMALE, statutory_blindness=case["blind"], disability_onset=case["onset"], - current_disability_period_established=True, - current_disability_period_provenance=observed, + current_disability_period_established=( + False if no_period else None if open_period else True + ), + current_disability_period_provenance=( + rule.EarningsProvenance.UNKNOWN if open_period else observed + ), current_disability_period_end=( None if unknown_end else case["ending"] ), current_disability_period_end_provenance=( rule.EarningsProvenance.UNKNOWN if unknown_end else observed ), + current_disability_period_continues_through=through, + current_disability_period_continues_through_provenance=( + rule.EarningsProvenance.UNKNOWN if through is None else observed + ), prior_disability_periods=tuple( rule.DisabilityPeriod( a, b, special_insured=case.get("special", False) @@ -484,6 +505,54 @@ def check_diagnostics(case, result, fillings): ), (case, upper, own) +def prior_can_begin(case, credits, periods): + """404.130(a), (e): even a blind prior begins fully insured. + + Each prior counts the periods before it or disregards them (404.130(f)). + """ + return all( + any( + disability(case["birth"], credits, quarter(begins), used, True) + for used in (periods[:index], ()) + ) + for index, (begins, _) in enumerate(periods) + ) + + +def prior_holds(case, credits, index): + """One declared prior's own start on one filling. + + Past blindness leaves no trace in a record, so an unflagged prior needs + only full insurance. A flagged prior's holder "were only insured under + paragraph (c)" (404.130(d)(1)). + """ + at = quarter(case["prior"][index][0]) + if not case.get("special"): + return any( + disability(case["birth"], credits, at, used, True) + for used in (case["prior"][:index], ()) + ) + return ( + disability(case["birth"], credits, at, (), False) + and recent(usable(credits, at, ()), at, (), 40) < 20 + ) + + +def fillings_keeping_priors(case, fillings): + """The fillings the declared priors allow. + + A prior no filling supports rests on something the record doesn't show, + and says nothing about placement. + """ + for index in range(len(case["prior"])): + fillings = [ + filling + for filling in fillings + if prior_holds(case, filling[7], index) + ] or fillings + return fillings + + def check(case): worlds = tuple( lawful_fillings(case, reading) @@ -496,6 +565,7 @@ def check(case): except InvalidFamilyInput as error: assert not any(worlds), (case, error) return "invalid" + worlds = tuple(fillings_keeping_priors(case, found) for found in worlds) actual = tuple( getattr(result, name).insured for name in ("fully", "currently", "disability") @@ -515,6 +585,94 @@ def check(case): return "computed" +def no_period_fillings(case, reading=LAST_40): + """Each filling of a record with no current period. + + The positions match ``lawful_fillings``, and no filling has a start. + """ + birth, month, blind = case["birth"], case["month"], case["blind"] + special = case.get("special", False) + at = quarter(month) + found = [] + for credits in placements(case["annual"]): + fully_best = currently_best = (False, -99, -1) + latest, insured = None, False + for periods in (case["prior"], ()): + use = usable(credits, at, periods) + needed = requirement(birth, month.year, periods) + held = recent(use, at, periods, 13) + fully_best = max( + fully_best, (len(use) >= needed, len(use) - needed, len(use)) + ) + currently_best = max(currently_best, (held >= 6, held - 6, held)) + latest = max( + filter( + None, + ( + latest, + last_insured( + birth, + credits, + at, + periods, + blind, + special, + reading, + ), + ), + ), + default=None, + ) + insured = insured or any( + disability( + birth, credits, candidate, periods, blind, special, reading + ) + for candidate in range(quarter(case["onset"]), at + 1) + ) + found.append( + ( + None, + fully_best[0], + currently_best[0], + insured, + fully_best, + currently_best, + latest, + credits, + ) + ) + return found + + +def check_no_period(case): + """Each result must be the best the declared priors allow.""" + case = {key: value for key, value in case.items() if key != "through"} + try: + result = public({**case, "no_period": True}) + except rule.InsuredConfigurationUnsupported: + return "refused" + for reading in READINGS if case.get("special") else READINGS[:1]: + fillings = fillings_keeping_priors( + case, no_period_fillings(case, reading) + ) + for name, index in (("fully", 1), ("currently", 2), ("disability", 3)): + assert getattr(result, name).insured == any( + filling[index] for filling in fillings + ), (case, name, reading, result) + for name, position in (("fully", 4), ("currently", 5)): + decision = getattr(result, name) + count = decision.qc_count_upper + assert (decision.insured, count - decision.required, count) == max( + filling[position] for filling in fillings + ), (case, name, reading, result) + upper = result.dli.upper + assert (None if upper is None else quarter(upper)) == max( + (filling[6] for filling in fillings if filling[6] is not None), + default=None, + ), (case, reading, upper) + return "computed" + + def quarter_end(value): year, number = divmod(value, 4) month = 3 * number + 3 @@ -536,21 +694,23 @@ def check_unknown_ending(case, unknown_prior=False): return "refused" except InvalidFamilyInput: return "invalid" - if result.current_disability_period_start is None: - return "no start" - start = quarter(result.current_disability_period_start) + reported = result.current_disability_period_start + start = None if reported is None else quarter(reported) endings = [ quarter_end(candidate) - for candidate in range(start, quarter(case["month"]) + 1) + for candidate in range( + quarter(case["onset"]) if start is None else start, + quarter(case["month"]) + 1, + ) ] best = [] for ending in (*endings, date(case["birth"].year + 70, 12, 31)): own = [ filling[6] for filling in lawful_fillings({**case, "ending": ending}) - if filling[0] == start + if start is None or filling[0] == start ] - assert own or unknown_prior, (case, ending, result) + assert own or unknown_prior or start is None, (case, ending, result) if own: best.append(max(-1 if found is None else found for found in own)) if not best: @@ -628,66 +788,152 @@ def check_unknown_ending(case, unknown_prior=False): }, } +# A prior from 1998Q1 needs 15 QCs and finds 14 before 1998, so it holds the 1998 +# QC in that quarter. The 40 quarters through 2008Q1 then hold 19. +PRIOR_DATE = { + "birth": date(1961, 2, 2), + "onset": date(2000, 1, 1), + "ending": date(2000, 12, 31), + "month": date(2008, 1, 1), + "blind": False, + "prior": (), + "annual": { + 1991: 2, + 1992: 4, + 1993: 4, + 1994: 4, + 1998: 1, + 1999: 4, + 2000: 4, + 2001: 4, + 2002: 4, + 2003: 3, + }, +} +# A prior from 1990Q1 needs six QCs and finds five before 1990, so it holds the +# 1990 QC in that quarter. The 2000Q1 start then holds the 2000 QC there, and the +# 13 quarters through 2003Q2 hold five. +PRIOR_STATUS = { + "birth": date(1965, 2, 2), + "onset": date(2000, 1, 1), + "ending": date(2002, 12, 31), + "through": date(2000, 1, 1), + "month": date(2003, 4, 1), + "blind": False, + "prior": (), + "annual": { + 1986: 4, + 1987: 1, + 1990: 1, + 1995: 3, + 1996: 4, + 1997: 4, + 1998: 4, + 1999: 4, + 2000: 1, + 2001: 4, + 2002: 1, + }, +} +# Only the 2000 QC in 2000Q1 reaches 20 of 40 through 2003Q2, and the 13 +# quarters through 2003Q2 hold six only with that QC later. +OPEN_STATUS = { + "birth": date(1965, 2, 2), + "onset": date(2000, 1, 1), + "ending": date(2003, 3, 31), + "month": date(2003, 4, 1), + "blind": False, + "prior": (), + "annual": { + 1990: 4, + 1991: 4, + 1992: 4, + 1993: 4, + 1994: 4, + 2000: 1, + 2001: 4, + 2002: 1, + }, +} + def added_priors(case): - """Undeclared priors that end before the onset, each past five months.""" + """Undeclared priors that end before the onset. + + The first three each run past five months, and the rest begin in a year of + annual credit, whose QC the prior's own start can hold early. + """ year = case["onset"].year + partial = sorted( + credited + for credited, count in case["annual"].items() + if count < 4 and credited < year + ) return tuple( ((date(year - back, month, 1), date(year - 1, 12, 31)),) for back, month in ((1, 4), (2, 1), (4, 1)) + ) + tuple( + ((date(credited, month, 1), date(year - 1, 12, 31)),) + for credited in partial + for month in (1, 7) ) -def prior_can_begin(case, credits, periods): - """404.130(a), (e): even a blind prior begins fully insured.""" - return all( - disability(case["birth"], credits, quarter(begins), (), True) - for begins, _ in periods - ) - - -def history_fillings(case, added, start, ending): - """Fillings with the reported start on a history holding ``added``.""" +def history_fillings(case, added, start, ending, *, dated=True): + """Fillings with a reported start on a history holding ``added``.""" return [ filling for filling in lawful_fillings( - {**case, "prior": added, "ending": ending} + {**case, "prior": added, "ending": ending}, + keep=lambda credits: prior_can_begin(case, credits, added), + dated=dated, ) - if filling[0] == start and prior_can_begin(case, filling[7], added) + if start is None or filling[0] == start ] -def check_every_history(case, unknown_end=False, test=rule.InsuredTest.ALL): - """No lawful prior history may undercut a computed result. +def check_every_history( + case, unknown_end=False, test=rule.InsuredTest.ALL, open_period=False +): + """No lawful completion may undercut a computed result. - UNKNOWN priors stand for each history below, so a filling with the - reported start has to hold each true status and reach the lower date on - it, whichever period ending the record has. + UNKNOWN priors stand for each history below, and UNKNOWN establishment for + a period on the record. Each completion's own starts limit its fillings, + and one of those fillings has to hold each true status and reach the lower + date, whichever period ending the record has. A start left open reads + every start. """ try: result = public( - {**case, "unknown_end": unknown_end, "unknown_prior": True}, + { + **case, + "unknown_end": unknown_end, + "unknown_prior": not open_period, + "open_period": open_period, + }, test=test, ) except rule.InsuredConfigurationUnsupported: return "refused" except InvalidFamilyInput: return "invalid" - if result.current_disability_period_start is None: - return "no start" - start = quarter(result.current_disability_period_start) + reported = result.current_disability_period_start + start = None if reported is None else quarter(reported) endings = (case["ending"],) - if unknown_end: + if unknown_end or open_period: + first = quarter(case["onset"]) if start is None else start endings = ( - quarter_end(start), + quarter_end(first), quarter_end(quarter(case["month"])), date(case["birth"].year + 70, 12, 31), ) fully, currently = result.fully, result.currently lower = None if result.dli is None else result.dli.lower - for added in added_priors(case): + for added in ((),) if open_period else ((), *added_priors(case)): for ending in endings: - held = history_fillings(case, added, start, ending) + held = history_fillings( + case, added, start, ending, dated=lower is not None + ) if not held: continue found = (case, added, ending, result) @@ -707,14 +953,28 @@ def check_every_history(case, unknown_end=False, test=rule.InsuredTest.ALL): return "computed" -def start_edge_declaration(seed): - """A record whose start needs the next QC, with its tail redrawn. +# 18 of 37 elapsed quarters pass the route at 1990Q2, and 20 of 40 pass the +# ordinary rule. +SPECIAL_PRIOR = { + "birth": date(1960, 2, 2), + "onset": date(1994, 1, 15), + "ending": date(1994, 12, 31), + "month": date(1995, 1, 1), + "blind": False, + "special": True, + "prior": ((date(1990, 4, 1), date(1991, 12, 31)),), + "annual": {1985: 2, 1986: 4, 1987: 4, 1988: 4, 1989: 4, 1990: 2}, +} + + +def edge_declaration(seed, cases): + """A record at an edge, with its tail redrawn. - Each draw keeps the QCs that put the start at the edge, and moves the + Each draw keeps the QCs that put the record at the edge, and moves the last QCs, the ending and the query around the record's own boundary. """ draw = random.Random(seed) - case = draw.choice((FREEZE_DATE, FREEZE_STATUS)) + case = draw.choice(cases) annual = dict(case["annual"]) last = max(annual) annual[last] = draw.randint(max(annual[last] - 1, 0), 4) @@ -725,6 +985,8 @@ def start_edge_declaration(seed): 1, ) ending = date(case["ending"].year + draw.randint(-1, 0), 12, 31) + if "through" in case: + ending = max(ending, case["through"]) return { **case, "ending": ending, @@ -733,6 +995,47 @@ def start_edge_declaration(seed): } +def start_edge_declaration(seed): + """A record whose start needs the next QC.""" + return edge_declaration(seed, (FREEZE_DATE, FREEZE_STATUS)) + + +def prior_edge_declaration(seed): + """A record whose result an earlier prior's start can undercut.""" + return edge_declaration(seed, (PRIOR_DATE, PRIOR_STATUS)) + + +def listed_prior_declaration(seed): + """The same records with the prior declared.""" + case = prior_edge_declaration(seed) + begins = date(1998 if case["birth"].year == 1961 else 1990, 1, 1) + return {**case, "prior": ((begins, date(1999, 12, 31)),)} + + +def two_prior_declaration(seed): + """The same records with an earlier prior a later one can rest on.""" + case = listed_prior_declaration(seed) + begins = case["prior"][0][0] + year = begins.year - random.Random(seed).randint(2, 5) + earlier = (date(year, 1, 1), date(year, 12, 31)) + return {**case, "prior": (earlier, *case["prior"])} + + +def special_prior_declaration(seed): + """A flagged prior whose route and ordinary rule both turn on 1990.""" + draw = random.Random(seed) + annual = { + **SPECIAL_PRIOR["annual"], + 1985: draw.randint(0, 4), + 1990: draw.randint(0, 4), + 1992: draw.randint(0, 4), + } + return { + **SPECIAL_PRIOR, + "annual": {year: n for year, n in annual.items() if n}, + } + + @pytest.mark.parametrize("seed", (5000026, 5000168)) def test_status_stress_year_counts_follow_the_returned_filling(seed): # The start's witness leaves a prior's interior holding a year's QCs. @@ -845,10 +1148,10 @@ def test_status_stress_an_added_prior_undercuts_the_freeze(unknown_end): assert (date_case, status_case) == ("refused", "refused") -def test_status_stress_a_date_with_no_period_in_force_holds_every_history(): +def test_status_stress_a_date_on_one_filling_refuses(): annual = {**FREEZE_DATE["annual"], 2005: 4} case = {**FREEZE_DATE, "annual": annual} - assert check_every_history(case, test=DISABILITY) == "computed" + assert check_every_history(case, test=DISABILITY) == "refused" def test_status_stress_a_status_with_no_period_in_force_holds_every_history(): @@ -893,6 +1196,91 @@ def test_status_stress_every_history_at_the_start_edge( check_every_history(start_edge_declaration(seed), unknown_end, test) +@pytest.mark.parametrize("unknown_end", (False, True)) +def test_status_stress_an_added_prior_holds_a_placement(unknown_end): + date_case = check_every_history(PRIOR_DATE, unknown_end, DISABILITY) + status_case = check_every_history(PRIOR_STATUS, unknown_end, CURRENTLY) + assert (date_case, status_case) == ("refused", "refused") + + +def test_status_stress_a_listed_prior_holds_a_placement(): + for begins, case in ((1998, PRIOR_DATE), (1990, PRIOR_STATUS)): + prior = ((date(begins, 1, 1), date(1999, 12, 31)),) + assert check({**case, "prior": prior}) == "refused" + + +def test_status_stress_a_later_prior_rests_on_an_earlier_one(): + earlier = (date(1995, 1, 1), date(1995, 12, 31)) + later = (date(1998, 1, 1), date(1999, 12, 31)) + annual = {y: n for y, n in PRIOR_DATE["annual"].items() if y != 1998} + case = {**PRIOR_DATE, "annual": annual, "prior": (earlier, later)} + assert check(case) == check_no_period(case) == "computed" + + +def test_status_stress_an_open_period_holds_a_placement(): + case = check_every_history(OPEN_STATUS, test=CURRENTLY, open_period=True) + assert case == "refused" + + +def test_status_stress_a_result_on_every_placement_computes(): + annual = {**PRIOR_DATE["annual"], 1998: 4} + case = {**PRIOR_DATE, "annual": annual} + assert check_every_history(case, test=DISABILITY) == "computed" + + +# A sweep of seeds 0 to 79 at 129d44bd found these two, where the generator +# reaches the reviewed head's defect. Its derandomized draws there missed it. +@settings(max_examples=30, deadline=None, derandomize=True) +@example(seed=1, unknown_end=False, test=DISABILITY) +@example(seed=5, unknown_end=True, test=CURRENTLY) +@given( + seed=st.integers(0, 2**32 - 1), + unknown_end=st.booleans(), + test=st.sampled_from((rule.InsuredTest.ALL, DISABILITY, CURRENTLY)), +) +def test_status_stress_every_history_at_a_prior_edge(seed, unknown_end, test): + check_every_history(prior_edge_declaration(seed), unknown_end, test) + + +@settings(max_examples=30, deadline=None, derandomize=True) +@given(seed=st.integers(0, 2**32 - 1)) +def test_status_stress_a_declared_prior_at_its_edge(seed): + check(listed_prior_declaration(seed)) + + +@settings(max_examples=30, deadline=None, derandomize=True) +@given(seed=st.integers(0, 2**32 - 1)) +def test_status_stress_two_declared_priors(seed): + check(two_prior_declaration(seed)) + + +@settings(max_examples=30, deadline=None, derandomize=True) +@given(seed=st.integers(0, 2**32 - 1)) +def test_status_stress_a_prior_with_no_current_period(seed): + check_no_period(listed_prior_declaration(seed)) + check_no_period(two_prior_declaration(seed)) + + +@settings(max_examples=30, deadline=None, derandomize=True) +@given(seed=st.integers(0, 2**32 - 1)) +def test_status_stress_a_flagged_prior_at_its_edge(seed): + check_no_period(special_prior_declaration(seed)) + + +# The same sweep found these two for UNKNOWN establishment. +@settings(max_examples=30, deadline=None, derandomize=True) +@example(seed=20, test=CURRENTLY) +@example(seed=33, test=rule.InsuredTest.ALL) +@given( + seed=st.integers(0, 2**32 - 1), + test=st.sampled_from((rule.InsuredTest.ALL, DISABILITY, CURRENTLY)), +) +def test_status_stress_every_open_period(seed, test): + unbound = {k: v for k, v in PRIOR_STATUS.items() if k != "through"} + case = edge_declaration(seed, (OPEN_STATUS, unbound)) + check_every_history(case, test=test, open_period=True) + + @settings(max_examples=20, deadline=None, derandomize=True) @given( seed=st.integers(0, 2**32 - 1), diff --git a/tests/tier_counts.json b/tests/tier_counts.json index a7bb05f9a..c80380ad6 100644 --- a/tests/tier_counts.json +++ b/tests/tier_counts.json @@ -1,7 +1,7 @@ { "schema_version": 1, "counts": { - "unit": 22127, + "unit": 22188, "artifact": 4271, "integration_psid": 1471, "reproduction_legacy": 520, From f9287518d57e54c81665d51ed74bd02b0dd29482 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Mon, 2 Nov 2026 15:09:28 -0500 Subject: [PATCH 26/46] Keep years after a period's start out of its filling (#562) Round 2's property test failed on 168bb3a8 for one invented input: a listed prior from 2000-04-02 to 2003-09-30, an established period from onset 2004-01-15, and 2, 3, 2, 2 and 2 QCs in 2016 to 2020. The concrete call refused with "More than 4096 first-start annual placements" after about 260 s. Round 17's start-keeping search enumerated every year up to the latest possible start, including the years after the reported one, and those years can't move it. Round 18's head refuses the same input. _fillings_keeping_start now enumerates only the years through the reported start. Whether a filling keeps a start turns only on quarters through it (404.321(a)), so later years stay flexible and each status places them favorably (RS 00301.230), as the logged reading us:oasdi-insured-one-filling-first-start says. The input computes in 2 s, and an @example on the round 2 test pins it. The design note gains a register of the module's ten source-conflict readings, each with the functions that hold its markers. The two markers that put their id on the next line now name it on the marker line, and tests/test_track_b_insured_status_readings.py holds the markers and the register to the same ids and functions. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 69 ++++++++++++++ .../track_b/insured_status.py | 16 ++-- tests/README-tiers.md | 4 +- ...test_track_b_insured_status_fix_round_2.py | 11 +++ tests/test_track_b_insured_status_readings.py | 95 +++++++++++++++++++ tests/tier_counts.json | 2 +- 6 files changed, 187 insertions(+), 10 deletions(-) create mode 100644 tests/test_track_b_insured_status_readings.py diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index 9fc9ccc5d..a8ccd2507 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -1639,6 +1639,75 @@ conditions; an explicitly declared fully insured route remains a supplied fact even if its cohort would not satisfy 404.112. These corrections make no payment adjudication and establish no dollar change. +## Source-conflict register + +Each `# Source conflict ` marker in `insured_status.py` and +`_insured_status_qc.py` names one of these ten readings on the marker's own +line. `tests/test_track_b_insured_status_readings.py` holds the markers and +this list to the same ids. Each reading changes classification and row weight +and computes no payment. + +- `us:oasdi-insured-prior-disability-favorable-disregard` (`_witness`). RS + 00301.140 example 9 prints that Sam isn't insured as of 5/93, and + 404.130(f) counts a prior period's quarters where that favors the worker. + The rule tries counting every prior period and disregarding them all, and + keeps the favorable result. +- `us:oasdi-insured-disability-period-endpoint-quarters` (`_allowed_quarters` + in `_insured_status_qc.py`). 404.130(f) keeps a period's first and last + quarters when each is a QC, and RS 00301.140 example 6 and RS 00301.147 + example 3 print counts without them. The rule keeps the endpoint quarters + eligible, and neither printed case changes its insured answer. +- `us:oasdi-insured-pre1951-seven-elapsed-years` + (`_pre1951_aggregate_possible`). Act 213(c) deems one QC for each $400 of + pre-1951 wages and states no seven-elapsed-year minimum, and RS 00301.315 + B.1 records the minimum and its later repeal. The bound applies no minimum, + and a potentially decisive aggregate refuses by name + (`simplified_pre1951_unsupported`). +- `us:oasdi-insured-simplified-pre1951-disability-scope` + (`_aggregate_could_insure`). Act 223(c)(1)(A), 216(i)(3)(A) and 404.132 + reach the fully insured prerequisite of disability insured status, and RS + 00301.315 B.1 says the simplified method doesn't apply to disability + claims. The rule follows the statute and the regulation, credits no deemed + quarter, and refuses by name where the aggregate could decide a disability + result. +- `us:oasdi-insured-pre1956-alternate-any-quarter-scan` + (`_pre1956_alternate_possible`). RS 00301.480 A bars the pre-1956 alternate + for a worker with 20/40 "in any quarter before 10/60", and its other words + reach only quarters the period covers. The scan stops at the latest date + every completion's period covers, and a possible route refuses by name + (`disability_before_1956_unsupported`). +- `us:oasdi-insured-historical-end-recovery-month` + (`_historical_recovery_month`). 404.321(b) ends a period on the last day of + the second month after the month the disability ended, and the interface + declares no recovery month. For an end before February 1981 that precedes + the FRA and death endings, recovery falls two months earlier, and that month + bounds a valid onset and start. FRA, death and paragraph (c) endings infer + no recovery. +- `us:oasdi-insured-unknown-prior-historical-blindness` + (`_unknown_prior_joint_shortfall`). Person fields declare current blindness + only, and 404.130(e) asks a blind worker for fully insured status alone. The + proof that no UNKNOWN prior can insure the current period therefore lets the + earliest prior rest on fully insured status, whatever `statutory_blindness` + says. +- `us:oasdi-insured-flag-first-insured-quarter` (`_recent_rule_possible`). + 404.321(a) starts a period in the first quarter its holder is insured, and a + fully-route flag declares fully insured status but not when it began. Only + ordinary insurance ends the scan of a filling. A quarter inside a prior + period that meets only the recent rule leaves the start open, so a later + quarter can still make the flag's establishment possible. +- `us:oasdi-insured-one-filling-first-start` (`_settle_first_start`, + `_settle_listed_priors`, `_settle_lower_date`, `_settle_every_history`). RS + 00301.230 makes annual placement flexible, and 404.321(a) gives a period one + start. Where placement can move a start, a result stands only if one filling + of the years that can move it keeps the start and attains the result. Other + years stay flexible for each status. +- `us:oasdi-insured-subsequent-special-long-period` (`_witness`, + `_unknown_prior_joint_shortfall`). Act 223(c)(1)(B)(iii) asks for half the + quarters after age 21 with no cap, and 404.130(d)(2) caps the test at 20 of + 40. `_witness` computes on the cap and refuses by name + (`subsequent_special_long_period_unsupported`) where the uncapped count + would insure, and the possibility proof takes the Act's reading. + ## Round 13 joint classification audit Sections 404.130(b)–(d) and (f) leave the recent floor intact when prior diff --git a/src/populace_dynamics/track_b/insured_status.py b/src/populace_dynamics/track_b/insured_status.py index da2d446b8..868f62291 100644 --- a/src/populace_dynamics/track_b/insured_status.py +++ b/src/populace_dynamics/track_b/insured_status.py @@ -1335,8 +1335,7 @@ def _witness( ) elif len(elapsed) > 40: window, required = elapsed[-40:], 20 - # Source conflict - # us:oasdi-insured-subsequent-special-long-period + # Source conflict us:oasdi-insured-subsequent-special-long-period # Half of over 40 quarters clears the fully count. long_period = long_period or ( len( @@ -1925,13 +1924,17 @@ def _improves(outcome, returned, last_insured): def _fillings_keeping_start( person, credits, start, month, exit_month, favored, binding ): - """Each placement and treatment keeping the start and binding priors.""" - horizon = _current_period_start_horizon(person, month) + """Each placement and treatment keeping the start and binding priors. + + Whether a filling keeps the start turns only on quarters through it + (404.321(a)), so no later year can move it. Those years stay flexible, + and each status places them favorably (RS00301.230). + """ witness = set( _witness(person, credits, start, exit_month, InsuredTest.DISABILITY)[4] ) sensitive = _start_sensitive_years( - person, person.disability_onset, horizon + person, person.disability_onset, start ) | _prior_sensitive_years(person, binding) def rank(choice): @@ -2531,8 +2534,7 @@ def special_recent(quarter, clock=clock, assigned=assigned): if len(elapsed) < 12: window, required = counted[-12:], 6 else: - # Source conflict - # us:oasdi-insured-subsequent-special-long-period + # Source conflict us:oasdi-insured-subsequent-special-long-period window, required = elapsed, max(6, len(elapsed) // 2) return len(set(window) & assigned) >= required diff --git a/tests/README-tiers.md b/tests/README-tiers.md index 187dc716b..aa2da2a6f 100644 --- a/tests/README-tiers.md +++ b/tests/README-tiers.md @@ -39,9 +39,9 @@ pytest --collect-only -q -m oracle_policyengine | tail -1 | Tier | Tests at HEAD | |---|---:| -| `unit` | 22,978 | +| `unit` | 22,982 | | `artifact` | 4,271 | | `integration_psid` | 1,471 | | `reproduction_legacy` | 520 | | `oracle_policyengine` | 337 | -| **Total** | **29,577** | +| **Total** | **29,581** | diff --git a/tests/test_track_b_insured_status_fix_round_2.py b/tests/test_track_b_insured_status_fix_round_2.py index de564fd55..533e21f26 100644 --- a/tests/test_track_b_insured_status_fix_round_2.py +++ b/tests/test_track_b_insured_status_fix_round_2.py @@ -280,6 +280,17 @@ def test_unknown_recent_and_fully_counts_contain_concrete_period_fillings( @PROPERTY +# Round 20: a listed prior, a 2004 start and partial years 2016-2020. The +# start-keeping search once enumerated those later years and refused. +@example( + start_year=2005, + end_year=2010, + recent=[2, 3, 2, 2, 2], + kind=i.InsuredTest.FULLY, + current_unknown=True, + early_current=True, + established_current=False, +) @example( start_year=2005, end_year=2015, diff --git a/tests/test_track_b_insured_status_readings.py b/tests/test_track_b_insured_status_readings.py new file mode 100644 index 000000000..af9f7916d --- /dev/null +++ b/tests/test_track_b_insured_status_readings.py @@ -0,0 +1,95 @@ +"""Statutory conformance: the insured-status source-conflict register. + +Invented data only; no population, behavioral or forecast claim. + +Each ``# Source conflict `` marker in the insured-status modules names its +reading on the marker's own line. The design note's register lists the same +readings, each with the functions that hold its markers. +""" + +import ast +import re +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +MODULES = ( + "src/populace_dynamics/track_b/insured_status.py", + "src/populace_dynamics/track_b/_insured_status_qc.py", +) +NOTE = ROOT / "docs/design/track_b_insured_status.md" +HEADING = "## Source-conflict register" +MARKER = re.compile(r"#\s*Source conflict\b(.*)$") +READING = re.compile(r"us:oasdi-insured-[a-z0-9]+(?:-[a-z0-9]+)*") +ENTRY = re.compile( + rf"^- `({READING.pattern})`\s*\(([^)]*)\)", flags=re.MULTILINE +) + + +def _markers(): + """Each marker's module, line, trailing text and top-level function.""" + found = [] + for module in MODULES: + text = (ROOT / module).read_text() + functions = [ + node + for node in ast.parse(text).body + if isinstance(node, ast.FunctionDef) + ] + for number, line in enumerate(text.splitlines(), 1): + match = MARKER.search(line) + if match is None: + continue + enclosing = [ + node.name + for node in functions + if node.lineno <= number <= node.end_lineno + ] + found.append( + ( + module, + number, + match.group(1).strip(), + enclosing[0] if enclosing else None, + ) + ) + return found + + +def _register(): + """Each register entry's reading and the functions it names.""" + text = NOTE.read_text() + assert text.count(f"\n{HEADING}\n") == 1 + section = text.split(f"\n{HEADING}\n", 1)[1].split("\n## ", 1)[0] + entries = ENTRY.findall(section) + assert len(entries) == section.count("\n- "), "unparsed register entry" + readings = [reading for reading, _ in entries] + assert len(readings) == len(set(readings)), "duplicate register entry" + return { + reading: set(re.findall(r"`([A-Za-z_][A-Za-z0-9_]*)`", sites)) + for reading, sites in entries + } + + +def test_every_marker_names_its_reading_on_the_marker_line(): + markers = _markers() + assert markers + for module, number, rest, _ in markers: + assert READING.fullmatch(rest), (module, number, rest) + + +def test_the_register_lists_exactly_the_markers_readings(): + assert {rest for _, _, rest, _ in _markers()} == set(_register()) + + +def test_each_marker_sits_in_a_function_its_entry_names(): + register = _register() + for module, number, rest, function in _markers(): + assert function in register.get(rest, ()), (module, number, function) + + +def test_each_named_function_holds_a_marker_for_its_reading(): + held = {(rest, function) for _, _, rest, function in _markers()} + for reading, functions in _register().items(): + assert functions, reading + for function in functions: + assert (reading, function) in held, (reading, function) diff --git a/tests/tier_counts.json b/tests/tier_counts.json index 346ea73e6..3a856d351 100644 --- a/tests/tier_counts.json +++ b/tests/tier_counts.json @@ -1,7 +1,7 @@ { "schema_version": 1, "counts": { - "unit": 22978, + "unit": 22982, "artifact": 4271, "integration_psid": 1471, "reproduction_legacy": 520, From 7d8cecbec39a802f04a7ab944297bd1219d725c0 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Mon, 2 Nov 2026 16:11:28 -0500 Subject: [PATCH 27/46] Kill round 19's four surviving mutations (#562) A cloud session reran round 19's 40 mutations at 168bb3a8 through every insured status module (PR comment 6584722299). Thirty-six failed a named test, and four passed every test. Nine new tests in tests/test_track_b_insured_status_fix_round_20.py kill each of the four, and the reverted round 20 fix: - binding_reaches_open_period: under UNKNOWN establishment the universal proof settles a result that a split listed prior can't move, so an UNKNOWN year leaves it computing. - disability_reads_the_completion: a period's establishment counts no quarter of its own period. - every_reads_listed_periods: the worst filling stays exact only with no period in force, since 404.130(f) and 404.146(d) keep a period's credited endpoint quarters. - flagged_refuses_every_placement: a flagged prior that every placement carries on its route, short of 20 of 40, binds nothing. - fix_reverted: a record whose later years hold 5,184 placements computes. Each mutation fails at least one new test in its own local process, and the unmodified source passes all nine. The design note gains round 20's section. round_19_mutations in the mutation ledger records the cloud rerun, decoded from the comment's gzip block. The tier files add nine unit tests (22,991 unit, 29,590 total). Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 125 ++- .../track_b_insured_status_mutations.json | 887 +++++++++++++++++- tests/README-tiers.md | 4 +- ...est_track_b_insured_status_fix_round_20.py | 367 ++++++++ tests/tier_counts.json | 2 +- 5 files changed, 1379 insertions(+), 6 deletions(-) create mode 100644 tests/test_track_b_insured_status_fix_round_20.py diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index a8ccd2507..9d0ad0ad7 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -2629,8 +2629,10 @@ and `date_search_drops_binding` survived, and `test_a_prior_reaches_a_year_the_start_cannot` and `test_a_listed_prior_holds_every_ending_to_the_date` now kill them. Two stress tests gained `@example` pins while that pass ran, so its results rest on mixed -test bytes. A rerun at the final bytes writes `round_19_mutations` in a later -commit. +test bytes. A cloud session reran all 40 at the final bytes, `168bb3a8`, +through every insured status module (`round_19_mutations` in +`docs/design/track_b_insured_status_mutations.json`). Thirty-six failed a +named test. Four passed every test, and round 20 kills them. Against `129d44bd`, 44 of the 162 tests then in the five changed modules fail. Three tests arrived later and two stress tests gained `@example` pins, and four @@ -2664,6 +2666,125 @@ These tests execute the invariants this round adds: (`test_a_special_prior_needs_a_quarter_of_its_route`, `test_a_special_prior_stays_short_of_the_ordinary_rule`). +## Round 20 a start's later years stay open + +Verification class: statutory conformance on invented declarations only. +This correction admits no population, behavioral, payment, or forecast claim. +A run of round 2's property test drew an invented input that `168bb3a8` +refuses, and the rerun of round 19's mutations left four alive. This round +fixes the first and kills the four. + +### Later years can't move a start + +An invented person born 1970-02-02 has four QCs in each of 1990 to 1999 and 2, +3, 2, 2 and 2 QCs in 2016 to 2020, a listed prior from 2000-04-02 through +2003-09-30, and an established period from an onset of 2004-01-15. For a +December 2020 query, `168bb3a8` refused the record with "More than 4096 +first-start annual placements". Round 17's `_fillings_keeping_start` asked +`_start_sensitive_years` for the years through the latest possible start +(`_current_period_start_horizon`), here the query month, so it counted the +5,184 placements of 2016 to 2020. The 2004 start rests on 1990 to 1999. + +A period begins at the onset or in the first later quarter that insures its +holder (404.321(a)), and each insured test at a quarter counts QCs through +that quarter only. Whether a +filling keeps a start therefore turns only on quarters through it, and no +later year can move it. `_fillings_keeping_start` now passes the reported +start in place of that horizon, so it enumerates only years through the +start, with the years a binding prior needs. Later years stay flexible, and +each status places them favorably (RS 00301.230), as the +logged reading `us:oasdi-insured-one-filling-first-start` says. The record +computes: with the period through the query, its 40 QCs of 1990 to 1999 meet +the eight elapsed years 1992 to 1999 +(`test_partial_years_after_the_start_stay_open`). +`test_a_filling_keeps_its_start_whatever_later_years_hold` draws records near +the 20-of-40 edge and checks that two fixed fillings that agree through a +start's year give that start. + +### Four survivors + +The rerun ran all 40 mutations through every insured status module, with no +restricted open. Four passed every test, and each now fails a test of this +round: + +- `binding_reaches_open_period` asks `_prior_start_binds` about a listed prior + under UNKNOWN establishment too. There `_settle_every_history` proves a + result every placement attains with no period in force, so a prior that + placement splits can't move it. The record of + `test_unknown_establishment_leaves_a_split_prior_to_the_proof`, with an + UNKNOWN 1997, computes a lower date of 2008-03-31 and fully and currently + insured status. The mutant refuses it by name + (`test_an_unknown_year_leaves_a_proven_result_to_the_proof`). +- `disability_reads_the_completion` has DISABILITY's search read the person + with the current period added, so the period's establishment skips the + period's own first quarter. Take round 19's 1961-born record with its 1998 + to 1999 prior listed and an established period from 2004-01-01 through + 2004-12-31. The prior holds the 1998 QC in 1998Q1, and the 40 counted + quarters through 2004Q1 hold 26 QCs. The mutant also skips 2004Q1, which + holds no QC, reaches back one more quarter and counts 27 + (`test_an_establishment_counts_no_quarter_of_its_own_period`). +- `every_reads_listed_periods` has `_prior_start_binds` test every placement + with the earlier priors in force. `_every_placement_passes` finds the worst + filling exactly only with no period in force, as its docstring says. A + period keeps its first and last quarters when they are QCs (404.130(f), + 404.146(d)), so an early QC can land on a credited endpoint and count where + a later one falls inside the period. An invented person born 1961-02-02 has + four QCs in each of 1987 and 1992 to 1994 and one in 1999, a prior from + 1999-01-01 through 2000-09-30, and a later prior from 2002-04-01 through + 2003-09-30. Past blindness asks the later prior for fully insured status + (404.130(e)). Counting the earlier period leaves 17 elapsed years, and + disregarding it leaves 19. The 1999 QC counts only in 1999Q1, so only that + placement reaches 17, and placement splits the later prior. The mutant's + worst filling puts the QC in 1999Q1 and finds every placement passing. + With an UNKNOWN 1997 the rule refuses the record by name, and the mutant + computes it (`test_a_later_prior_on_an_earlier_endpoint_binds`, + `test_an_unknown_year_refuses_that_later_prior`). + `test_a_later_prior_placement_splits_binds` draws pairs of priors. It checks + `_prior_passes` on each fixed filling against the oracle, and it checks that + `_prior_start_binds` answers true wherever those fillings split and false + where none holds the prior. +- `flagged_refuses_every_placement` drops the clause that releases a flagged + prior every placement carries. That prior's holder "were only insured under + paragraph (c)" (404.130(d)(1)). When every placement passes its route and + none reaches 20 of 40, the prior holds on every placement and binds nothing. + Round 19's 1960-born record has a flagged prior from 1990-04-01 through + 1991-12-31, two QCs in 1985, four in each of 1986 to 1989 and one in 1990. + With an UNKNOWN 1993 the rule computes fully insured status, and the mutant + refuses the record by name + (`test_an_unknown_year_leaves_a_special_prior_every_placement_carries`). + `test_a_special_prior_every_placement_carries_binds_nothing` checks the + predicate against the oracle on drawn records. + +Restoring the horizon (`fix_reverted`) makes +`test_partial_years_after_the_start_stay_open` refuse again. Each of the four +survivors and `fix_reverted` fails at least one of this round's nine tests, +and the unmodified source passes all nine. Each ran in its own process on +invented data, with both data roots set to a nonexistent path. A rerun of +round 19's 40 mutations and `fix_reverted` at the final bytes, through every +insured status module, writes `round_20_mutations` in a later commit. + +These tests execute the invariants this round adds: + +- placement of the years after a start never moves it: two fixed fillings + that agree through a start's year give that start + (`test_a_filling_keeps_its_start_whatever_later_years_hold`), and a record + whose later years hold more than 4,096 placements computes + (`test_partial_years_after_the_start_stay_open`); +- under UNKNOWN establishment, a result every placement attains with no period + in force stands, however placement splits a listed prior + (`test_an_unknown_year_leaves_a_proven_result_to_the_proof`); +- DISABILITY's count for a period's establishment skips no quarter of that + period (`test_an_establishment_counts_no_quarter_of_its_own_period`); +- `_prior_passes` on a fixed filling agrees with the oracle for a later prior + counted with an earlier one, and `_prior_start_binds` answers true wherever + placement splits the prior and false where no placement holds it + (`test_a_later_prior_placement_splits_binds`, + `test_a_later_prior_on_an_earlier_endpoint_binds`); +- a flagged prior that every placement carries on its route, short of 20 of + 40, binds nothing + (`test_a_special_prior_every_placement_carries_binds_nothing`, + `test_an_unknown_year_leaves_a_special_prior_every_placement_carries`). + ## Not in scope No real data, population evaluation, baseline claiming hazard, behavioral diff --git a/docs/design/track_b_insured_status_mutations.json b/docs/design/track_b_insured_status_mutations.json index cd7c7988d..650c39f4a 100644 --- a/docs/design/track_b_insured_status_mutations.json +++ b/docs/design/track_b_insured_status_mutations.json @@ -6577,5 +6577,890 @@ "tests/test_track_b_insured_status_fix_round_17.py": "9d7357bd0caf1915fd4b1cba8c8746aae2b54a48b4ce1d0dfe9b13c29625c2f8" }, "round_18_replay": "Write round_18_runner_source to scratch/review/run_round18_named.py. For each round_18_mutations record, write name/source_sha256/changes to its spec_path, then execute its exact command. Mutations apply only in memory.", - "round_18_final_source_sha256": "a2f2e761041d2bf71622a46ce3cd466c49b6d5b6a92bff452552b34d65607118" + "round_18_final_source_sha256": "a2f2e761041d2bf71622a46ce3cd466c49b6d5b6a92bff452552b34d65607118", + "round_19_mutations": [ + { + "changes": [ + { + "after": " chosen = vacant[:count]\n", + "before": " chosen = vacant[-count:] if year == at.year else vacant[:count]\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-worst_always_early.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/worst_always_early /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_status_on_every_placement_computes" + ], + "log": "scratch/review/round19-mutation-worst_always_early.log", + "name": "worst_always_early", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-worst_always_early.json" + }, + { + "changes": [ + { + "after": " chosen = vacant[-count:]\n", + "before": " chosen = vacant[-count:] if year == at.year else vacant[:count]\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-worst_always_late.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/worst_always_late /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_date[known_end]" + ], + "log": "scratch/review/round19-mutation-worst_always_late.log", + "name": "worst_always_late", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-worst_always_late.json" + }, + { + "changes": [ + { + "after": " if _witness(\n person,\n lower,\n person.disability_onset,\n coverage_end_month,\n InsuredTest.DISABILITY,\n )[0]:\n lo_start = hi_start = person.disability_onset\n", + "before": " if _start_fixed(\n person,\n lower,\n person.disability_onset,\n month,\n coverage_end_month,\n ):\n lo_start = hi_start = person.disability_onset\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-start_on_favorable_placement.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/start_on_favorable_placement /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_status_on_every_placement_computes" + ], + "log": "scratch/review/round19-mutation-start_on_favorable_placement.log", + "name": "start_on_favorable_placement", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-start_on_favorable_placement.json" + }, + { + "changes": [ + { + "after": "", + "before": " if prior_unknown or current_unknown:\n _settle_every_history(\n person, lower, month, coverage_end_month, decisions, dli\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-no_universal_proof.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/no_universal_proof /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_date[known_end]" + ], + "log": "scratch/review/round19-mutation-no_universal_proof.log", + "name": "no_universal_proof", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-no_universal_proof.json" + }, + { + "changes": [ + { + "after": " if prior_unknown:\n _settle_every_history(", + "before": " if prior_unknown or current_unknown:\n _settle_every_history(" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-proof_skips_open_period.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/proof_skips_open_period /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_unknown_establishment_alone_refuses[InsuredTest.ALL]" + ], + "log": "scratch/review/round19-mutation-proof_skips_open_period.log", + "name": "proof_skips_open_period", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-proof_skips_open_period.json" + }, + { + "changes": [ + { + "after": " if current_unknown:\n _settle_every_history(", + "before": " if prior_unknown or current_unknown:\n _settle_every_history(" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-proof_skips_unknown_priors.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/proof_skips_unknown_priors /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_date[known_end]" + ], + "log": "scratch/review/round19-mutation-proof_skips_unknown_priors.log", + "name": "proof_skips_unknown_priors", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-proof_skips_unknown_priors.json" + }, + { + "changes": [ + { + "after": " _settle_every_history(\n person, upper, month,", + "before": " _settle_every_history(\n person, lower, month," + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-proof_on_upper_credits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/proof_on_upper_credits /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_date[unknown_year]" + ], + "log": "scratch/review/round19-mutation-proof_on_upper_credits.log", + "name": "proof_on_upper_credits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-proof_on_upper_credits.json" + }, + { + "changes": [ + { + "after": " if (\n decision is not None\n and False\n and not _every_placement_passes(\n", + "before": " if (\n decision is not None\n and decision.insured\n and not _every_placement_passes(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-proof_skips_statuses.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/proof_skips_statuses /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_status[first_day-InsuredTest.ALL]" + ], + "log": "scratch/review/round19-mutation-proof_skips_statuses.log", + "name": "proof_skips_statuses", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-proof_skips_statuses.json" + }, + { + "changes": [ + { + "after": " if (\n dli is not None\n and False\n and not _every_placement_passes(\n", + "before": " if (\n dli is not None\n and dli.lower is not None\n and not _every_placement_passes(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-proof_skips_the_date.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/proof_skips_the_date /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_date[known_end]" + ], + "log": "scratch/review/round19-mutation-proof_skips_the_date.log", + "name": "proof_skips_the_date", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-proof_skips_the_date.json" + }, + { + "changes": [ + { + "after": " month,\n", + "before": " decision.qualifying_quarter,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-status_tested_at_query.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/status_tested_at_query /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_status_stands_at_the_quarter_it_reports" + ], + "log": "scratch/review/round19-mutation-status_tested_at_query.log", + "name": "status_tested_at_query", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-status_tested_at_query.json" + }, + { + "changes": [ + { + "after": " month,\n", + "before": " _qdate(_qid(dli.lower)),\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-date_tested_at_query.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/date_tested_at_query /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_2.py::test_unknown_period_status_and_dli_bounds_contain_concrete_fillings" + ], + "log": "scratch/review/round19-mutation-date_tested_at_query.log", + "name": "date_tested_at_query", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-date_tested_at_query.json" + }, + { + "changes": [ + { + "after": " bare = person\n for kind, decision", + "before": " bare = replace(person, prior_disability_periods=())\n for kind, decision" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-proof_keeps_listed_priors.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/proof_keeps_listed_priors /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_unknown_establishment_needs_the_disregard" + ], + "log": "scratch/review/round19-mutation-proof_keeps_listed_priors.log", + "name": "proof_keeps_listed_priors", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-proof_keeps_listed_priors.json" + }, + { + "changes": [ + { + "after": " if False\n", + "before": " if not current_unknown\n and _prior_start_binds(\n person, lower, upper, index, month, coverage_end_month\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-no_listed_prior_check.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/no_listed_prior_check /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_listed_prior_can_undercut_the_date" + ], + "log": "scratch/review/round19-mutation-no_listed_prior_check.log", + "name": "no_listed_prior_check", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-no_listed_prior_check.json" + }, + { + "changes": [ + { + "after": " if _prior_start_binds(\n person, lower, upper, index, month, coverage_end_month\n )\n", + "before": " if not current_unknown\n and _prior_start_binds(\n person, lower, upper, index, month, coverage_end_month\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-binding_reaches_open_period.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/binding_reaches_open_period /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 0, + "failing_test_nodes": [], + "log": "scratch/review/round19-mutation-binding_reaches_open_period.log", + "name": "binding_reaches_open_period", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-binding_reaches_open_period.json" + }, + { + "changes": [ + { + "after": " if False:\n", + "before": " if binding and unknown:\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-unknown_year_searches.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/unknown_year_searches /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_an_unknown_year_reaches_a_listed_prior[every_needs_lower_credits]" + ], + "log": "scratch/review/round19-mutation-unknown_year_searches.log", + "name": "unknown_year_searches", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-unknown_year_searches.json" + }, + { + "changes": [ + { + "after": " True\n or not (", + "before": " _prior_passes(person, filling, index, exit_month)\n and not (" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-keeps_every_filling.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/keeps_every_filling /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_listed_prior_can_undercut_the_date" + ], + "log": "scratch/review/round19-mutation-keeps_every_filling.log", + "name": "keeps_every_filling", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-keeps_every_filling.json" + }, + { + "changes": [ + { + "after": "", + "before": " and not (\n person.prior_disability_periods[index].special_insured\n and _prior_passes(\n person, filling, index, exit_month, ordinary_only=True\n )\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-keeps_ignores_the_flag.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/keeps_ignores_the_flag /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_special_prior_stays_short_of_the_ordinary_rule" + ], + "log": "scratch/review/round19-mutation-keeps_ignores_the_flag.log", + "name": "keeps_ignores_the_flag", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-keeps_ignores_the_flag.json" + }, + { + "changes": [ + { + "after": "", + "before": " if not _keeps_priors(person, filling, binding, exit_month):\n continue\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-start_search_ignores_priors.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/start_search_ignores_priors /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_listed_prior_can_undercut_the_date" + ], + "log": "scratch/review/round19-mutation-start_search_ignores_priors.log", + "name": "start_search_ignores_priors", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-start_search_ignores_priors.json" + }, + { + "changes": [ + { + "after": "", + "before": " if _keeps_priors(person, filling, binding, exit_month)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-listed_search_ignores_priors.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/listed_search_ignores_priors /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_listed_prior_binds_without_a_current_period" + ], + "log": "scratch/review/round19-mutation-listed_search_ignores_priors.log", + "name": "listed_search_ignores_priors", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-listed_search_ignores_priors.json" + }, + { + "changes": [ + { + "after": " year\n for index in ()\n", + "before": " year\n for index in binding\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-no_prior_years.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/no_prior_years /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_listed_prior_binds_without_a_current_period" + ], + "log": "scratch/review/round19-mutation-no_prior_years.log", + "name": "no_prior_years", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-no_prior_years.json" + }, + { + "changes": [ + { + "after": " )\n", + "before": " ) | _prior_sensitive_years(person, binding)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-start_search_skips_prior_years.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/start_search_skips_prior_years /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_reaches_a_year_the_start_cannot" + ], + "log": "scratch/review/round19-mutation-start_search_skips_prior_years.log", + "name": "start_search_skips_prior_years", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-start_search_skips_prior_years.json" + }, + { + "changes": [ + { + "after": " person, credits, start, month, exit_month, favored, ()\n ),\n start,\n", + "before": " person, credits, start, month, exit_month, favored, binding\n ),\n start,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-first_search_drops_binding.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/first_search_drops_binding /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_listed_prior_can_undercut_the_status" + ], + "log": "scratch/review/round19-mutation-first_search_drops_binding.log", + "name": "first_search_drops_binding", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-first_search_drops_binding.json" + }, + { + "changes": [ + { + "after": " for filling, completed in _fillings_keeping_start(\n person, credits, start, month, exit_month, favored, ()\n", + "before": " for filling, completed in _fillings_keeping_start(\n person, credits, start, month, exit_month, favored, binding\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-date_search_drops_binding.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/date_search_drops_binding /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_listed_prior_holds_every_ending_to_the_date" + ], + "log": "scratch/review/round19-mutation-date_search_drops_binding.log", + "name": "date_search_drops_binding", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-date_search_drops_binding.json" + }, + { + "changes": [ + { + "after": "", + "before": " *((InsuredTest.DISABILITY,) if binding else ()),\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-disability_left_out_of_search.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/disability_left_out_of_search /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_limits_what_a_status_reports" + ], + "log": "scratch/review/round19-mutation-disability_left_out_of_search.log", + "name": "disability_left_out_of_search", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-disability_left_out_of_search.json" + }, + { + "changes": [ + { + "after": " option,\n", + "before": " person if kind is InsuredTest.DISABILITY else option,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-disability_reads_the_completion.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/disability_reads_the_completion /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 0, + "failing_test_nodes": [], + "log": "scratch/review/round19-mutation-disability_reads_the_completion.log", + "name": "disability_reads_the_completion", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-disability_reads_the_completion.json" + }, + { + "changes": [ + { + "after": " dated=False,\n last_insured=last_insured,\n reported=reported,\n detail=\"Annual placement decides", + "before": " dated=dated,\n last_insured=last_insured,\n reported=reported,\n detail=\"Annual placement decides" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-listed_search_skips_the_date.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/listed_search_skips_the_date /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_holds_a_qc_in_its_first_quarter" + ], + "log": "scratch/review/round19-mutation-listed_search_skips_the_date.log", + "name": "listed_search_skips_the_date", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-listed_search_skips_the_date.json" + }, + { + "changes": [ + { + "after": " return not every()\n", + "before": " return not every() and some()\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-unflagged_refuses_unsupported_prior.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/unflagged_refuses_unsupported_prior /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_no_placement_supports_stands_as_declared" + ], + "log": "scratch/review/round19-mutation-unflagged_refuses_unsupported_prior.log", + "name": "unflagged_refuses_unsupported_prior", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-unflagged_refuses_unsupported_prior.json" + }, + { + "changes": [ + { + "after": " return some()\n", + "before": " return not every() and some()\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-unflagged_refuses_every_placement.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/unflagged_refuses_every_placement /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_placement_binds_a_prior_only_when_it_splits_them" + ], + "log": "scratch/review/round19-mutation-unflagged_refuses_every_placement.log", + "name": "unflagged_refuses_every_placement", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-unflagged_refuses_every_placement.json" + }, + { + "changes": [ + { + "after": " return (\n True\n and not every(ordinary_only=True)\n and not (every() and not some(ordinary_only=True))\n )\n", + "before": " return (\n some()\n and not every(ordinary_only=True)\n and not (every() and not some(ordinary_only=True))\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-flagged_ignores_support.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/flagged_ignores_support /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_special_prior_short_of_its_route_stands_as_declared" + ], + "log": "scratch/review/round19-mutation-flagged_ignores_support.log", + "name": "flagged_ignores_support", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-flagged_ignores_support.json" + }, + { + "changes": [ + { + "after": " return (\n some()\n and True\n and not (every() and not some(ordinary_only=True))\n )\n", + "before": " return (\n some()\n and not every(ordinary_only=True)\n and not (every() and not some(ordinary_only=True))\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-flagged_ignores_ordinary_rule.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/flagged_ignores_ordinary_rule /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_special_prior_no_placement_supports_stands_as_declared" + ], + "log": "scratch/review/round19-mutation-flagged_ignores_ordinary_rule.log", + "name": "flagged_ignores_ordinary_rule", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-flagged_ignores_ordinary_rule.json" + }, + { + "changes": [ + { + "after": " return (\n some()\n and not every(ordinary_only=True)\n and True\n )\n", + "before": " return (\n some()\n and not every(ordinary_only=True)\n and not (every() and not some(ordinary_only=True))\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-flagged_refuses_every_placement.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/flagged_refuses_every_placement /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 0, + "failing_test_nodes": [], + "log": "scratch/review/round19-mutation-flagged_refuses_every_placement.log", + "name": "flagged_refuses_every_placement", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-flagged_refuses_every_placement.json" + }, + { + "changes": [ + { + "after": " statutory_blindness=True,\n", + "before": " statutory_blindness=not flagged,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-every_flagged_reads_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/every_flagged_reads_blindness /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_reaches_a_year_the_start_cannot" + ], + "log": "scratch/review/round19-mutation-every_flagged_reads_blindness.log", + "name": "every_flagged_reads_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-every_flagged_reads_blindness.json" + }, + { + "changes": [ + { + "after": " statutory_blindness=False,\n", + "before": " statutory_blindness=not flagged,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-every_unflagged_reads_no_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/every_unflagged_reads_no_blindness /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_placement_binds_a_prior_only_when_it_splits_them" + ], + "log": "scratch/review/round19-mutation-every_unflagged_reads_no_blindness.log", + "name": "every_unflagged_reads_no_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-every_unflagged_reads_no_blindness.json" + }, + { + "changes": [ + { + "after": " statutory_blindness=True,\n", + "before": " statutory_blindness=not period.special_insured,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-route_flagged_reads_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/route_flagged_reads_blindness /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_holds_a_qc_in_its_first_quarter" + ], + "log": "scratch/review/round19-mutation-route_flagged_reads_blindness.log", + "name": "route_flagged_reads_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-route_flagged_reads_blindness.json" + }, + { + "changes": [ + { + "after": " statutory_blindness=False,\n", + "before": " statutory_blindness=not period.special_insured,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-route_unflagged_reads_no_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/route_unflagged_reads_no_blindness /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_listed_prior_can_undercut_the_date" + ], + "log": "scratch/review/round19-mutation-route_unflagged_reads_no_blindness.log", + "name": "route_unflagged_reads_no_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-route_unflagged_reads_no_blindness.json" + }, + { + "changes": [ + { + "after": " prior_disability_periods=person.prior_disability_periods[:index],\n )\n\n def every(**options):\n", + "before": " prior_disability_periods=(),\n )\n\n def every(**options):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-every_reads_listed_periods.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/every_reads_listed_periods /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 0, + "failing_test_nodes": [], + "log": "scratch/review/round19-mutation-every_reads_listed_periods.log", + "name": "every_reads_listed_periods", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-every_reads_listed_periods.json" + }, + { + "changes": [ + { + "after": " prior_disability_periods=(),\n )\n return _witness(\n", + "before": " prior_disability_periods=person.prior_disability_periods[:index],\n )\n return _witness(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-some_drops_earlier_periods.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/some_drops_earlier_periods /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_later_prior_counts_the_earlier_one_on_every_filling" + ], + "log": "scratch/review/round19-mutation-some_drops_earlier_periods.log", + "name": "some_drops_earlier_periods", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-some_drops_earlier_periods.json" + }, + { + "changes": [ + { + "after": " bare,\n upper,\n period.start,\n", + "before": " bare,\n lower,\n period.start,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-every_on_upper_credits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/every_on_upper_credits /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_an_unknown_year_reaches_a_listed_prior[every_needs_lower_credits]" + ], + "log": "scratch/review/round19-mutation-every_on_upper_credits.log", + "name": "every_on_upper_credits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-every_on_upper_credits.json" + }, + { + "changes": [ + { + "after": " return _prior_passes(person, lower, index, exit_month, **options)\n", + "before": " return _prior_passes(person, upper, index, exit_month, **options)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-some_on_lower_credits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/some_on_lower_credits /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_an_unknown_year_reaches_a_listed_prior[some_needs_upper_credits]" + ], + "log": "scratch/review/round19-mutation-some_on_lower_credits.log", + "name": "some_on_lower_credits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-some_on_lower_credits.json" + }, + { + "changes": [ + { + "after": " if young or subsequent:\n", + "before": " if (young or subsequent) and not ordinary_only:\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round19 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round19 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND19_MUTATION=scratch/review/round19-mutation-ordinary_keeps_special_route.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp19/ordinary_keeps_special_route /tmp/tbvenv/bin/python scratch/review/run_round19_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_holds_a_qc_in_its_first_quarter" + ], + "log": "scratch/review/round19-mutation-ordinary_keeps_special_route.log", + "name": "ordinary_keeps_special_route", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "spec_path": "scratch/review/round19-mutation-ordinary_keeps_special_route.json" + } + ], + "round_19_runner_source": "\"\"\"Run named invented-data conformance tests with open-event auditing.\"\"\"\n\nimport hashlib\nimport json\nimport os\nfrom pathlib import Path\nimport sys\n\nCOUNTS = {\"restricted_opens\": 0, \"subprocess.Popen\": 0, \"os.system\": 0}\nBARRED = {\n \"gates.yaml\", \"adjusted_poverty.py\", \"rows.py\",\n \"ssa_trust_fund_interest_rates_2026.json\",\n \"urban2010_cola_comparison.md\", \"urban2010_fra68_comparison.md\",\n \"boomers2004_uniform_cut_comparison.md\", \"minimum_benefits_comparison.md\",\n \"m6_projection_engine.md\", \"mint8_table_user_guide.source.html\",\n \"test_anchor_provenance_erratum.py\",\n \"s0_1_power_results.json\", \"s0_1_source_audit.md\", \"s0_1_power.py\",\n \"test_s0_1_invariants.py\", \"test_s0_1_power.py\",\n \"test_s0_1_thresholds.py\",\n}\n\n\ndef audit(event, arguments):\n if event == \"open\" and isinstance(arguments[0], (str, bytes)):\n path = os.fsdecode(arguments[0])\n name = Path(path).name\n if (\n name in BARRED\n or name.startswith((\"adjusted_poverty.\", \"rows.\"))\n or \"/PolicyEngine/psid-data/\" in path\n or \"/microcosm-launch-evidence/\" in path\n or \"/dynasim-refs/\" in path\n or \"/claude-501/\" in path\n or \"/tests/s0_1/\" in path\n ):\n COUNTS[\"restricted_opens\"] += 1\n raise RuntimeError(path)\n elif event in (\"subprocess.Popen\", \"os.system\"):\n COUNTS[event] += 1\n\n\ndef main():\n for name in (\"POPULACE_DYNAMICS_PSID_DIR\", \"POPULACE_DYNAMICS_EPUF_DIR\"):\n assert os.environ[name] == \"/nonexistent/trackb-round19\"\n assert sys.argv[1:]\n assert all(\n not argument.startswith(\"tests/\") or \".py\" in argument\n for argument in sys.argv[1:]\n )\n sys.addaudithook(audit)\n from populace_dynamics.track_b import insured_status as insured\n\n source_path = Path(insured.__file__)\n original = source_path.read_bytes()\n baseline_path = os.environ.get(\"TRACKB_ROUND16_SOURCE\")\n if baseline_path:\n baseline = Path(baseline_path).read_bytes()\n exec(compile(baseline, str(source_path), \"exec\"), insured.__dict__)\n print(\"BASELINE\", hashlib.sha256(baseline).hexdigest(), flush=True)\n spec_path = os.environ.get(\"TRACKB_ROUND19_MUTATION\")\n if spec_path:\n spec = json.loads(Path(spec_path).read_text())\n assert hashlib.sha256(original).hexdigest() == spec[\"source_sha256\"]\n source = original.decode()\n for change in spec[\"changes\"]:\n assert source.count(change[\"before\"]) == 1, change[\"before\"]\n source = source.replace(change[\"before\"], change[\"after\"], 1)\n exec(compile(source, str(source_path), \"exec\"), insured.__dict__)\n print(\"MUTATION\", spec[\"name\"], flush=True)\n import pytest\n\n try:\n return pytest.main(sys.argv[1:])\n finally:\n assert source_path.read_bytes() == original\n print(\"OPEN_AUDIT\", json.dumps(COUNTS, sort_keys=True), flush=True)\n\n\nif __name__ == \"__main__\":\n raise SystemExit(main())\n", + "round_19_note": "A cloud session ran round 19's 40 mutations at 168bb3a8, the final round 19 source and test bytes, against every insured status module, with no restricted open (PR #562 comment 6584722299). Thirty-six failed a named test. binding_reaches_open_period, disability_reads_the_completion, every_reads_listed_periods and flagged_refuses_every_placement passed every test, and round 20's tests kill them.", + "round_19_test_sha256": { + "tests/test_track_b_insured_status_fix_round_19.py": "5075e9aa563740106a5e080fa23f4f9d928ebaa2c10e1f4afe575f10c5bd4d0e", + "tests/test_track_b_insured_status_status_stress.py": "f6e96aca3cb607c28f538b088751c1dae7252c4ae8df0837e4e147ab4482deac", + "tests/test_track_b_insured_status_fix_round_18.py": "b4bf594a55df126421950a890f6a089ec18f13bac2ef7a94431af1606d384c1b", + "tests/test_track_b_insured_status_fix_round_17.py": "1f7751a66198a84356bf5c0ea76e12d4bcfbf2181cfbc3e337970dfbe16e5449", + "tests/test_track_b_insured_status_fix_round_2.py": "661daf018a36655260373f0f50869f93626883aedc486ffe6a6844e83b2c0556" + }, + "round_19_replay": "Write round_19_runner_source to scratch/review/run_round19_named.py. For each round_19_mutations record, write name/source_sha256/changes to its spec_path, then execute its exact command at 168bb3a8. Mutations apply only in memory.", + "round_19_final_source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24" } diff --git a/tests/README-tiers.md b/tests/README-tiers.md index aa2da2a6f..4b306db10 100644 --- a/tests/README-tiers.md +++ b/tests/README-tiers.md @@ -39,9 +39,9 @@ pytest --collect-only -q -m oracle_policyengine | tail -1 | Tier | Tests at HEAD | |---|---:| -| `unit` | 22,982 | +| `unit` | 22,991 | | `artifact` | 4,271 | | `integration_psid` | 1,471 | | `reproduction_legacy` | 520 | | `oracle_policyengine` | 337 | -| **Total** | **29,581** | +| **Total** | **29,590** | diff --git a/tests/test_track_b_insured_status_fix_round_20.py b/tests/test_track_b_insured_status_fix_round_20.py new file mode 100644 index 000000000..d8e09afc1 --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_20.py @@ -0,0 +1,367 @@ +"""Round 20: a start's later years stay open. + +Verification class: statutory conformance on invented declarations; no +population, behavioral or forecast claim. + +Whether a filling keeps a period's start turns only on quarters through it +(404.321(a)), so no later year can move it, and each status places those years +favorably (RS 00301.230; source conflict +us:oasdi-insured-one-filling-first-start). + +The round 19 mutation rerun left four mutations alive, and a test below kills +each. A result every placement attains needs no search of a split prior. A +period's establishment counts no quarter of its own. The worst filling is +exact only with no period in force (404.146(d) keeps a period's credited +endpoints). A special prior that every placement carries binds nothing. +""" + +from dataclasses import replace +from datetime import date, timedelta + +import pytest +from hypothesis import assume, example, given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as i +from populace_dynamics.track_b.gross_benefits import InvalidFamilyInput +from tests.test_track_b_insured_status import history +from tests.test_track_b_insured_status_fix_round_2 import ( + _person as _declared_person, +) +from tests.test_track_b_insured_status_fix_round_17 import ( + ASSIGNMENT, + OBSERVED, + _history, + _person, + _result, +) +from tests.test_track_b_insured_status_fix_round_19 import ( + ANNUAL, + DATE_ANNUAL, + DATE_BIRTH, + DATE_PRIOR, + SPECIAL_BASE, + UNKNOWN_ESTABLISHMENT, + _credits, + _date_person, + _lawful_prior, + _special_person, + _unknown_year, +) +from tests.test_track_b_insured_status_status_stress import ( + disability, + placements, + quarter, +) + +FULLY = i.InsuredTest.FULLY +DISABILITY = i.InsuredTest.DISABILITY +MONTH = date(2005, 1, 1) +LISTED_PRIOR = ( + "Annual placement decides a listed prior's first insured quarter" +) + + +def _qdate(credit): + return date(credit // 4, 3 * (credit % 4) + 1, 1) + + +def _qend(credit): + return _qdate(credit + 1) - timedelta(days=1) + + +def _filling(annual, credits): + """One placement of ``annual`` as fixed quarters for each year.""" + return { + year: (tuple(sorted(c for c in credits if c // 4 == year)), 0) + for year in annual + } + + +def _refusal(person, years, month, **options): + with pytest.raises(i.InsuredConfigurationUnsupported) as error: + i.insured_status(person, years, month, **options) + return error.value + + +# Later years. + + +def test_partial_years_after_the_start_stay_open(): + # A 2004 start rests on 1990 to 1999, so the 5,184 placements of 2016 to + # 2020 can't move it. With the period through the query, the 40 QCs of + # 1990 to 1999 meet the eight elapsed years 1992 to 1999. + person = _declared_person( + date(1970, 2, 2), + prior_disability_periods=( + i.DisabilityPeriod(date(2000, 4, 2), date(2003, 9, 30)), + ), + disability_onset=date(2004, 1, 15), + current_disability_period_established=True, + ) + month = date(2020, 12, 1) + counts = dict.fromkeys(range(1990, 2000), 4) + counts.update(zip(range(2016, 2021), (2, 3, 2, 2, 2), strict=True)) + result = i.insured_status( + person, history(person, month, counts), month, test=FULLY + ) + assert result.current_disability_period_start == date(2004, 1, 15) + assert result.fully.insured + assert (result.fully.qc_count_lower, result.fully.required) == (40, 8) + + +@settings(max_examples=40, deadline=None, derandomize=True) +@given( + onset=st.dates(date(1996, 1, 1), date(2002, 12, 31)), + full=st.sets(st.integers(-8, -1), min_size=4, max_size=6), + near=st.integers(-1, 0), + count=st.integers(1, 3), + later=st.dictionaries( + st.integers(1, 5), st.integers(1, 3), min_size=1, max_size=2 + ), + prior=st.booleans(), +) +def test_a_filling_keeps_its_start_whatever_later_years_hold( + onset, full, near, count, later, prior +): + # Four to six full years before the onset, a partial year at or just + # before it and one or two partial years after it, so the start sits + # near the 20-of-40 edge and the later years hold placements to vary. + annual = { + **{onset.year + offset: 4 for offset in full}, + onset.year + near: count, + **{onset.year + offset: n for offset, n in later.items()}, + } + person = i.Person( + date(1964, 2, 2), + sex=i.Sex.FEMALE, + disability_onset=onset, + current_disability_period_established=True, + current_disability_period_provenance=OBSERVED, + prior_disability_periods=( + (i.DisabilityPeriod(date(1990, 1, 1), date(1991, 12, 31)),) + if prior + else () + ), + prior_disability_periods_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + starts = {} + for credits in placements(annual): + try: + starts[credits] = i._with_current_period( + person, _filling(annual, credits), date(2008, 1, 1), None + )[1] + except (InvalidFamilyInput, i.InsuredConfigurationUnsupported): + starts[credits] = None + for credits, start in starts.items(): + if start is None: + continue + through = {c for c in credits if c // 4 <= start.year} + for other, found in starts.items(): + if {c for c in other if c // 4 <= start.year} == through: + assert found == start, (annual, onset, sorted(other)) + + +# A result every placement attains. + + +def test_an_unknown_year_leaves_a_proven_result_to_the_proof(): + # Every placement attains this result with no period in force, on every + # completion of an UNKNOWN 1997 too, so the split prior can't move it. + annual = {**DATE_ANNUAL, **dict.fromkeys(range(2004, 2008), 4)} + result = _result( + _date_person( + **UNKNOWN_ESTABLISHMENT, + prior_disability_periods=(DATE_PRIOR,), + prior_disability_periods_provenance=OBSERVED, + ), + _unknown_year(_history(1961, 2008, annual), 1997), + date(2008, 1, 1), + ) + assert result.dli.lower == date(2008, 3, 31) + assert result.fully.insured + assert result.currently.insured + + +# A period's own quarters. + + +def test_an_establishment_counts_no_quarter_of_its_own_period(): + # The prior holds the 1998 QC in 1998Q1, so it binds, and DISABILITY joins + # the search. Counting the prior skips its six interior quarters, so the + # 40 quarters through 2004Q1 reach 1992Q4 and hold 26 QCs. The period + # begins in 2004Q1, which holds no QC. Excluding that quarter would reach + # 1992Q3 for 27, and the period would rest on its own exclusion. + result = _result( + _date_person( + disability_onset=date(2004, 1, 1), + current_disability_period_end=date(2004, 12, 31), + prior_disability_periods=(DATE_PRIOR,), + prior_disability_periods_provenance=OBSERVED, + ), + _history(1961, 2005, DATE_ANNUAL), + date(2005, 1, 1), + test=DISABILITY, + ) + assert result.current_disability_period_start == date(2004, 1, 1) + assert result.assigned_quarters[1998] == (1998 * 4,) + found = result.disability + assert (found.qc_count_lower, found.qc_count_upper) == (26, 26) + assert found.qualifying_quarter == date(2004, 1, 1) + + +# A later prior on an earlier period's credited endpoint. + +ENDPOINT_ANNUAL = {1987: 4, 1992: 4, 1993: 4, 1994: 4, 1999: 1} +EARLIER = i.DisabilityPeriod(date(1999, 1, 1), date(2000, 9, 30)) +LATER = i.DisabilityPeriod(date(2002, 4, 1), date(2003, 9, 30)) + + +def _endpoint_person(): + return replace( + _person(EARLIER, LATER, disability_onset=None), birth_date=DATE_BIRTH + ) + + +def _later_holds(birth, credits, earlier, later): + """Past blindness asks for fully insured status at the later start.""" + at = quarter(later.start) + return disability( + birth, credits, at, ((earlier.start, earlier.end),), True + ) or disability(birth, credits, at, (), True) + + +def test_a_later_prior_on_an_earlier_endpoint_binds(): + # Counting the 1999 period leaves 17 elapsed years before 2002, and 16 QCs + # fall in 1987 and 1992 to 1994. The 1999 QC counts only in 1999Q1, the + # period's credited first quarter (404.146(d)), and disregarding the + # period asks for 19. The worst filling puts that QC in 1999Q1, so with + # the period listed it passes where a 1999Q2 filling fails. + person = _endpoint_person() + held = { + _later_holds(DATE_BIRTH, credits, EARLIER, LATER) + for credits in placements(ENDPOINT_ANNUAL) + } + assert held == {False, True} + credits = _credits(ENDPOINT_ANNUAL) + listed = replace( + person, statutory_blindness=True, prior_disability_periods=(EARLIER,) + ) + assert i._every_placement_passes( + listed, credits, LATER.start, MONTH, None, DISABILITY + ) + interior = {**credits, 1999: ((1999 * 4 + 1,), 0)} + assert not i._prior_passes(person, interior, 1, None) + assert i._prior_start_binds(person, credits, credits, 1, MONTH, None) + + +def test_an_unknown_year_refuses_that_later_prior(): + # An UNKNOWN 1997 runs from none, where only a 1999Q1 QC holds the later + # prior, to four, where every placement does. + refused = _refusal( + _endpoint_person(), + _unknown_year(_history(1961, 2004, ENDPOINT_ANNUAL), 1997), + date(2004, 1, 1), + ) + assert refused.reason is ASSIGNMENT + assert refused.detail == LISTED_PRIOR + + +@settings(max_examples=60, deadline=None, derandomize=True) +@example( + annual=ENDPOINT_ANNUAL, + earlier_start=quarter(EARLIER.start), + earlier_length=quarter(EARLIER.end) - quarter(EARLIER.start), + gap=quarter(LATER.start) - quarter(EARLIER.end), + later_length=quarter(LATER.end) - quarter(LATER.start), +) +@given( + annual=ANNUAL, + earlier_start=st.integers(1986 * 4, 2000 * 4 + 3), + earlier_length=st.integers(0, 7), + gap=st.integers(1, 16), + later_length=st.integers(0, 6), +) +def test_a_later_prior_placement_splits_binds( + annual, earlier_start, earlier_length, gap, later_length +): + later_start = earlier_start + earlier_length + gap + assume(later_start + later_length <= 2004 * 4 + 3) + earlier = i.DisabilityPeriod( + _qdate(earlier_start), _qend(earlier_start + earlier_length) + ) + later = i.DisabilityPeriod( + _qdate(later_start), _qend(later_start + later_length) + ) + person = replace( + _person(earlier, later, disability_onset=None), birth_date=DATE_BIRTH + ) + held = set() + for credits in placements(annual): + expected = _later_holds(DATE_BIRTH, credits, earlier, later) + assert ( + i._prior_passes(person, _filling(annual, credits), 1, None) + is expected + ), (annual, earlier, later, sorted(credits)) + held.add(expected) + credits = _credits(annual) + binds = i._prior_start_binds(person, credits, credits, 1, MONTH, None) + assert binds or len(held) == 1, (annual, earlier, later) + assert not binds or True in held, (annual, earlier, later) + + +# A special prior every placement carries. + + +def test_an_unknown_year_leaves_a_special_prior_every_placement_carries(): + # Eighteen QCs pass the route on every placement, and one 1990 QC can't + # reach 20 of 40. An UNKNOWN 1993 follows the prior and can't reach its + # start, so the prior binds nothing and the status computes. + result = _result( + _special_person(), + _unknown_year(_history(1960, 1995, {**SPECIAL_BASE, 1990: 1}), 1993), + date(1995, 1, 1), + test=FULLY, + ) + assert result.fully.insured + + +@settings(max_examples=100, deadline=None, derandomize=True) +@example( + annual={1985: 4, 1986: 4, 1987: 4, 1988: 4, 1989: 3}, + begins_year=1990, + begins_quarter=3, +) +@given( + annual=ANNUAL, + begins_year=st.integers(1986, 1990), + begins_quarter=st.integers(0, 3), +) +def test_a_special_prior_every_placement_carries_binds_nothing( + annual, begins_year, begins_quarter +): + # 404.130(d)(1)'s holder "were only insured under paragraph (c)". When + # every placement passes the route and stays short of 20 of 40, no + # placement can unseat the prior. + birth = date(1960, 2, 2) + begins = date(begins_year, 3 * begins_quarter + 1, 1) + prior = i.DisabilityPeriod( + begins, date(begins_year, 12, 31), special_insured=True + ) + person = i.Person( + birth, + sex=i.Sex.FEMALE, + prior_disability_periods=(prior,), + prior_disability_periods_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + held = { + _lawful_prior(birth, credits, begins, True) + for credits in placements(annual) + } + credits = _credits(annual) + binds = i._prior_start_binds(person, credits, credits, 0, MONTH, None) + assert held != {True} or not binds, (annual, begins) diff --git a/tests/tier_counts.json b/tests/tier_counts.json index 3a856d351..b111850dc 100644 --- a/tests/tier_counts.json +++ b/tests/tier_counts.json @@ -1,7 +1,7 @@ { "schema_version": 1, "counts": { - "unit": 22982, + "unit": 22991, "artifact": 4271, "integration_psid": 1471, "reproduction_legacy": 520, From 38a573a86f78d81775f23817592953b3ac5d5872 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Mon, 2 Nov 2026 16:12:50 -0500 Subject: [PATCH 28/46] Record which round 20 tests fail against 168bb3a8 (#562) Against 168bb3a8, 6 of the 32 tests in the three changed modules fail: round 2's pinned record, test_partial_years_after_the_start_stay_open, and the four register tests, since that head has no register. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index 9d0ad0ad7..be279857d 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -2763,6 +2763,10 @@ invented data, with both data roots set to a nonexistent path. A rerun of round 19's 40 mutations and `fix_reverted` at the final bytes, through every insured status module, writes `round_20_mutations` in a later commit. +Against `168bb3a8`, 6 of the 32 tests in the three changed modules fail: +round 2's pinned record, `test_partial_years_after_the_start_stay_open`, and +the four register tests, since that head has no register. + These tests execute the invariants this round adds: - placement of the years after a start never moves it: two fixed fillings From 6eb708aaa904beed40414e6f72d1ba9ab818b38a Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Mon, 2 Nov 2026 17:23:21 -0500 Subject: [PATCH 29/46] Record round 20's 41 mutation kills from the cloud run (#562) A cloud session reran the 41 mutations at 38a573a8 through every insured status module (PR #562 comment 6589941045). All 41 failed a named test, with no restricted open. The records carry 38a573a8's source and test hashes, so the replay stays pinned to that head. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 7 +- .../track_b_insured_status_mutations.json | 919 +++++++++++++++++- 2 files changed, 922 insertions(+), 4 deletions(-) diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index be279857d..eef1a15c9 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -2759,9 +2759,10 @@ Restoring the horizon (`fix_reverted`) makes `test_partial_years_after_the_start_stay_open` refuse again. Each of the four survivors and `fix_reverted` fails at least one of this round's nine tests, and the unmodified source passes all nine. Each ran in its own process on -invented data, with both data roots set to a nonexistent path. A rerun of -round 19's 40 mutations and `fix_reverted` at the final bytes, through every -insured status module, writes `round_20_mutations` in a later commit. +invented data, with both data roots set to a nonexistent path. A cloud session +then reran round 19's 40 mutations and `fix_reverted` at `38a573a8`, through +every insured status module. All 41 failed a named test, with no restricted +open (`round_20_mutations`, PR #562 comment 6589941045). Against `168bb3a8`, 6 of the 32 tests in the three changed modules fail: round 2's pinned record, `test_partial_years_after_the_start_stay_open`, and diff --git a/docs/design/track_b_insured_status_mutations.json b/docs/design/track_b_insured_status_mutations.json index 650c39f4a..cd16c5bf4 100644 --- a/docs/design/track_b_insured_status_mutations.json +++ b/docs/design/track_b_insured_status_mutations.json @@ -7462,5 +7462,922 @@ "tests/test_track_b_insured_status_fix_round_2.py": "661daf018a36655260373f0f50869f93626883aedc486ffe6a6844e83b2c0556" }, "round_19_replay": "Write round_19_runner_source to scratch/review/run_round19_named.py. For each round_19_mutations record, write name/source_sha256/changes to its spec_path, then execute its exact command at 168bb3a8. Mutations apply only in memory.", - "round_19_final_source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24" + "round_19_final_source_sha256": "e33723c056fdef01ca035bc335995faadc27e9f712e8071813e7128708021f24", + "round_20_mutations": [ + { + "changes": [ + { + "after": " chosen = vacant[:count]\n", + "before": " chosen = vacant[-count:] if year == at.year else vacant[:count]\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-worst_always_early.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/worst_always_early /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_a_later_prior_placement_splits_binds" + ], + "log": "scratch/review/round20-mutation-worst_always_early.log", + "name": "worst_always_early", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-worst_always_early.json" + }, + { + "changes": [ + { + "after": " chosen = vacant[-count:]\n", + "before": " chosen = vacant[-count:] if year == at.year else vacant[:count]\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-worst_always_late.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/worst_always_late /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_a_later_prior_on_an_earlier_endpoint_binds" + ], + "log": "scratch/review/round20-mutation-worst_always_late.log", + "name": "worst_always_late", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-worst_always_late.json" + }, + { + "changes": [ + { + "after": " if _witness(\n person,\n lower,\n person.disability_onset,\n coverage_end_month,\n InsuredTest.DISABILITY,\n )[0]:\n lo_start = hi_start = person.disability_onset\n", + "before": " if _start_fixed(\n person,\n lower,\n person.disability_onset,\n month,\n coverage_end_month,\n ):\n lo_start = hi_start = person.disability_onset\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-start_on_favorable_placement.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/start_on_favorable_placement /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_status_on_every_placement_computes" + ], + "log": "scratch/review/round20-mutation-start_on_favorable_placement.log", + "name": "start_on_favorable_placement", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-start_on_favorable_placement.json" + }, + { + "changes": [ + { + "after": "", + "before": " if prior_unknown or current_unknown:\n _settle_every_history(\n person, lower, month, coverage_end_month, decisions, dli\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-no_universal_proof.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/no_universal_proof /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_date[known_end]" + ], + "log": "scratch/review/round20-mutation-no_universal_proof.log", + "name": "no_universal_proof", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-no_universal_proof.json" + }, + { + "changes": [ + { + "after": " if prior_unknown:\n _settle_every_history(", + "before": " if prior_unknown or current_unknown:\n _settle_every_history(" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-proof_skips_open_period.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/proof_skips_open_period /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_unknown_establishment_alone_refuses[InsuredTest.ALL]" + ], + "log": "scratch/review/round20-mutation-proof_skips_open_period.log", + "name": "proof_skips_open_period", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-proof_skips_open_period.json" + }, + { + "changes": [ + { + "after": " if current_unknown:\n _settle_every_history(", + "before": " if prior_unknown or current_unknown:\n _settle_every_history(" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-proof_skips_unknown_priors.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/proof_skips_unknown_priors /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_date[known_end]" + ], + "log": "scratch/review/round20-mutation-proof_skips_unknown_priors.log", + "name": "proof_skips_unknown_priors", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-proof_skips_unknown_priors.json" + }, + { + "changes": [ + { + "after": " _settle_every_history(\n person, upper, month,", + "before": " _settle_every_history(\n person, lower, month," + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-proof_on_upper_credits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/proof_on_upper_credits /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_date[unknown_year]" + ], + "log": "scratch/review/round20-mutation-proof_on_upper_credits.log", + "name": "proof_on_upper_credits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-proof_on_upper_credits.json" + }, + { + "changes": [ + { + "after": " if (\n decision is not None\n and False\n and not _every_placement_passes(\n", + "before": " if (\n decision is not None\n and decision.insured\n and not _every_placement_passes(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-proof_skips_statuses.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/proof_skips_statuses /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_status[first_day-InsuredTest.ALL]" + ], + "log": "scratch/review/round20-mutation-proof_skips_statuses.log", + "name": "proof_skips_statuses", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-proof_skips_statuses.json" + }, + { + "changes": [ + { + "after": " if (\n dli is not None\n and False\n and not _every_placement_passes(\n", + "before": " if (\n dli is not None\n and dli.lower is not None\n and not _every_placement_passes(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-proof_skips_the_date.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/proof_skips_the_date /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_date[known_end]" + ], + "log": "scratch/review/round20-mutation-proof_skips_the_date.log", + "name": "proof_skips_the_date", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-proof_skips_the_date.json" + }, + { + "changes": [ + { + "after": " month,\n", + "before": " decision.qualifying_quarter,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-status_tested_at_query.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/status_tested_at_query /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_status_stands_at_the_quarter_it_reports" + ], + "log": "scratch/review/round20-mutation-status_tested_at_query.log", + "name": "status_tested_at_query", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-status_tested_at_query.json" + }, + { + "changes": [ + { + "after": " month,\n", + "before": " _qdate(_qid(dli.lower)),\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-date_tested_at_query.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/date_tested_at_query /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_2.py::test_unknown_period_status_and_dli_bounds_contain_concrete_fillings" + ], + "log": "scratch/review/round20-mutation-date_tested_at_query.log", + "name": "date_tested_at_query", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-date_tested_at_query.json" + }, + { + "changes": [ + { + "after": " bare = person\n for kind, decision", + "before": " bare = replace(person, prior_disability_periods=())\n for kind, decision" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-proof_keeps_listed_priors.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/proof_keeps_listed_priors /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_unknown_establishment_needs_the_disregard" + ], + "log": "scratch/review/round20-mutation-proof_keeps_listed_priors.log", + "name": "proof_keeps_listed_priors", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-proof_keeps_listed_priors.json" + }, + { + "changes": [ + { + "after": " if False\n", + "before": " if not current_unknown\n and _prior_start_binds(\n person, lower, upper, index, month, coverage_end_month\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-no_listed_prior_check.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/no_listed_prior_check /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_an_unknown_year_refuses_that_later_prior" + ], + "log": "scratch/review/round20-mutation-no_listed_prior_check.log", + "name": "no_listed_prior_check", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-no_listed_prior_check.json" + }, + { + "changes": [ + { + "after": " if _prior_start_binds(\n person, lower, upper, index, month, coverage_end_month\n )\n", + "before": " if not current_unknown\n and _prior_start_binds(\n person, lower, upper, index, month, coverage_end_month\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-binding_reaches_open_period.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/binding_reaches_open_period /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_an_unknown_year_leaves_a_proven_result_to_the_proof" + ], + "log": "scratch/review/round20-mutation-binding_reaches_open_period.log", + "name": "binding_reaches_open_period", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-binding_reaches_open_period.json" + }, + { + "changes": [ + { + "after": " if False:\n", + "before": " if binding and unknown:\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-unknown_year_searches.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/unknown_year_searches /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_an_unknown_year_refuses_that_later_prior" + ], + "log": "scratch/review/round20-mutation-unknown_year_searches.log", + "name": "unknown_year_searches", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-unknown_year_searches.json" + }, + { + "changes": [ + { + "after": " True\n or not (", + "before": " _prior_passes(person, filling, index, exit_month)\n and not (" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-keeps_every_filling.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/keeps_every_filling /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_listed_prior_can_undercut_the_date" + ], + "log": "scratch/review/round20-mutation-keeps_every_filling.log", + "name": "keeps_every_filling", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-keeps_every_filling.json" + }, + { + "changes": [ + { + "after": "", + "before": " and not (\n person.prior_disability_periods[index].special_insured\n and _prior_passes(\n person, filling, index, exit_month, ordinary_only=True\n )\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-keeps_ignores_the_flag.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/keeps_ignores_the_flag /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_special_prior_stays_short_of_the_ordinary_rule" + ], + "log": "scratch/review/round20-mutation-keeps_ignores_the_flag.log", + "name": "keeps_ignores_the_flag", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-keeps_ignores_the_flag.json" + }, + { + "changes": [ + { + "after": "", + "before": " if not _keeps_priors(person, filling, binding, exit_month):\n continue\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-start_search_ignores_priors.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/start_search_ignores_priors /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_listed_prior_can_undercut_the_date" + ], + "log": "scratch/review/round20-mutation-start_search_ignores_priors.log", + "name": "start_search_ignores_priors", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-start_search_ignores_priors.json" + }, + { + "changes": [ + { + "after": "", + "before": " if _keeps_priors(person, filling, binding, exit_month)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-listed_search_ignores_priors.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/listed_search_ignores_priors /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_listed_prior_binds_without_a_current_period" + ], + "log": "scratch/review/round20-mutation-listed_search_ignores_priors.log", + "name": "listed_search_ignores_priors", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-listed_search_ignores_priors.json" + }, + { + "changes": [ + { + "after": " year\n for index in ()\n", + "before": " year\n for index in binding\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-no_prior_years.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/no_prior_years /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_listed_prior_binds_without_a_current_period" + ], + "log": "scratch/review/round20-mutation-no_prior_years.log", + "name": "no_prior_years", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-no_prior_years.json" + }, + { + "changes": [ + { + "after": " )\n", + "before": " ) | _prior_sensitive_years(person, binding)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-start_search_skips_prior_years.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/start_search_skips_prior_years /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_reaches_a_year_the_start_cannot" + ], + "log": "scratch/review/round20-mutation-start_search_skips_prior_years.log", + "name": "start_search_skips_prior_years", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-start_search_skips_prior_years.json" + }, + { + "changes": [ + { + "after": " person, credits, start, month, exit_month, favored, ()\n ),\n start,\n", + "before": " person, credits, start, month, exit_month, favored, binding\n ),\n start,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-first_search_drops_binding.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/first_search_drops_binding /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_listed_prior_can_undercut_the_status" + ], + "log": "scratch/review/round20-mutation-first_search_drops_binding.log", + "name": "first_search_drops_binding", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-first_search_drops_binding.json" + }, + { + "changes": [ + { + "after": " for filling, completed in _fillings_keeping_start(\n person, credits, start, month, exit_month, favored, ()\n", + "before": " for filling, completed in _fillings_keeping_start(\n person, credits, start, month, exit_month, favored, binding\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-date_search_drops_binding.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/date_search_drops_binding /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_listed_prior_holds_every_ending_to_the_date" + ], + "log": "scratch/review/round20-mutation-date_search_drops_binding.log", + "name": "date_search_drops_binding", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-date_search_drops_binding.json" + }, + { + "changes": [ + { + "after": "", + "before": " *((InsuredTest.DISABILITY,) if binding else ()),\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-disability_left_out_of_search.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/disability_left_out_of_search /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_limits_what_a_status_reports" + ], + "log": "scratch/review/round20-mutation-disability_left_out_of_search.log", + "name": "disability_left_out_of_search", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-disability_left_out_of_search.json" + }, + { + "changes": [ + { + "after": " option,\n", + "before": " person if kind is InsuredTest.DISABILITY else option,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-disability_reads_the_completion.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/disability_reads_the_completion /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_an_establishment_counts_no_quarter_of_its_own_period" + ], + "log": "scratch/review/round20-mutation-disability_reads_the_completion.log", + "name": "disability_reads_the_completion", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-disability_reads_the_completion.json" + }, + { + "changes": [ + { + "after": " dated=False,\n last_insured=last_insured,\n reported=reported,\n detail=\"Annual placement decides", + "before": " dated=dated,\n last_insured=last_insured,\n reported=reported,\n detail=\"Annual placement decides" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-listed_search_skips_the_date.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/listed_search_skips_the_date /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_holds_a_qc_in_its_first_quarter" + ], + "log": "scratch/review/round20-mutation-listed_search_skips_the_date.log", + "name": "listed_search_skips_the_date", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-listed_search_skips_the_date.json" + }, + { + "changes": [ + { + "after": " return not every()\n", + "before": " return not every() and some()\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-unflagged_refuses_unsupported_prior.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/unflagged_refuses_unsupported_prior /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_a_later_prior_placement_splits_binds" + ], + "log": "scratch/review/round20-mutation-unflagged_refuses_unsupported_prior.log", + "name": "unflagged_refuses_unsupported_prior", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-unflagged_refuses_unsupported_prior.json" + }, + { + "changes": [ + { + "after": " return some()\n", + "before": " return not every() and some()\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-unflagged_refuses_every_placement.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/unflagged_refuses_every_placement /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_placement_binds_a_prior_only_when_it_splits_them" + ], + "log": "scratch/review/round20-mutation-unflagged_refuses_every_placement.log", + "name": "unflagged_refuses_every_placement", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-unflagged_refuses_every_placement.json" + }, + { + "changes": [ + { + "after": " return (\n True\n and not every(ordinary_only=True)\n and not (every() and not some(ordinary_only=True))\n )\n", + "before": " return (\n some()\n and not every(ordinary_only=True)\n and not (every() and not some(ordinary_only=True))\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-flagged_ignores_support.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/flagged_ignores_support /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_special_prior_short_of_its_route_stands_as_declared" + ], + "log": "scratch/review/round20-mutation-flagged_ignores_support.log", + "name": "flagged_ignores_support", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-flagged_ignores_support.json" + }, + { + "changes": [ + { + "after": " return (\n some()\n and True\n and not (every() and not some(ordinary_only=True))\n )\n", + "before": " return (\n some()\n and not every(ordinary_only=True)\n and not (every() and not some(ordinary_only=True))\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-flagged_ignores_ordinary_rule.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/flagged_ignores_ordinary_rule /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_special_prior_no_placement_supports_stands_as_declared" + ], + "log": "scratch/review/round20-mutation-flagged_ignores_ordinary_rule.log", + "name": "flagged_ignores_ordinary_rule", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-flagged_ignores_ordinary_rule.json" + }, + { + "changes": [ + { + "after": " return (\n some()\n and not every(ordinary_only=True)\n and True\n )\n", + "before": " return (\n some()\n and not every(ordinary_only=True)\n and not (every() and not some(ordinary_only=True))\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-flagged_refuses_every_placement.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/flagged_refuses_every_placement /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_an_unknown_year_leaves_a_special_prior_every_placement_carries" + ], + "log": "scratch/review/round20-mutation-flagged_refuses_every_placement.log", + "name": "flagged_refuses_every_placement", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-flagged_refuses_every_placement.json" + }, + { + "changes": [ + { + "after": " statutory_blindness=True,\n", + "before": " statutory_blindness=not flagged,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-every_flagged_reads_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/every_flagged_reads_blindness /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_reaches_a_year_the_start_cannot" + ], + "log": "scratch/review/round20-mutation-every_flagged_reads_blindness.log", + "name": "every_flagged_reads_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-every_flagged_reads_blindness.json" + }, + { + "changes": [ + { + "after": " statutory_blindness=False,\n", + "before": " statutory_blindness=not flagged,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-every_unflagged_reads_no_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/every_unflagged_reads_no_blindness /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_placement_binds_a_prior_only_when_it_splits_them" + ], + "log": "scratch/review/round20-mutation-every_unflagged_reads_no_blindness.log", + "name": "every_unflagged_reads_no_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-every_unflagged_reads_no_blindness.json" + }, + { + "changes": [ + { + "after": " statutory_blindness=True,\n", + "before": " statutory_blindness=not period.special_insured,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-route_flagged_reads_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/route_flagged_reads_blindness /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_an_unknown_year_leaves_a_special_prior_every_placement_carries" + ], + "log": "scratch/review/round20-mutation-route_flagged_reads_blindness.log", + "name": "route_flagged_reads_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-route_flagged_reads_blindness.json" + }, + { + "changes": [ + { + "after": " statutory_blindness=False,\n", + "before": " statutory_blindness=not period.special_insured,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-route_unflagged_reads_no_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/route_unflagged_reads_no_blindness /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_a_later_prior_on_an_earlier_endpoint_binds" + ], + "log": "scratch/review/round20-mutation-route_unflagged_reads_no_blindness.log", + "name": "route_unflagged_reads_no_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-route_unflagged_reads_no_blindness.json" + }, + { + "changes": [ + { + "after": " prior_disability_periods=person.prior_disability_periods[:index],\n )\n\n def every(**options):\n", + "before": " prior_disability_periods=(),\n )\n\n def every(**options):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-every_reads_listed_periods.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/every_reads_listed_periods /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_a_later_prior_on_an_earlier_endpoint_binds" + ], + "log": "scratch/review/round20-mutation-every_reads_listed_periods.log", + "name": "every_reads_listed_periods", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-every_reads_listed_periods.json" + }, + { + "changes": [ + { + "after": " prior_disability_periods=(),\n )\n return _witness(\n", + "before": " prior_disability_periods=person.prior_disability_periods[:index],\n )\n return _witness(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-some_drops_earlier_periods.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/some_drops_earlier_periods /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_a_later_prior_on_an_earlier_endpoint_binds" + ], + "log": "scratch/review/round20-mutation-some_drops_earlier_periods.log", + "name": "some_drops_earlier_periods", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-some_drops_earlier_periods.json" + }, + { + "changes": [ + { + "after": " bare,\n upper,\n period.start,\n", + "before": " bare,\n lower,\n period.start,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-every_on_upper_credits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/every_on_upper_credits /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_an_unknown_year_refuses_that_later_prior" + ], + "log": "scratch/review/round20-mutation-every_on_upper_credits.log", + "name": "every_on_upper_credits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-every_on_upper_credits.json" + }, + { + "changes": [ + { + "after": " return _prior_passes(person, lower, index, exit_month, **options)\n", + "before": " return _prior_passes(person, upper, index, exit_month, **options)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-some_on_lower_credits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/some_on_lower_credits /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_an_unknown_year_reaches_a_listed_prior[some_needs_upper_credits]" + ], + "log": "scratch/review/round20-mutation-some_on_lower_credits.log", + "name": "some_on_lower_credits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-some_on_lower_credits.json" + }, + { + "changes": [ + { + "after": " if young or subsequent:\n", + "before": " if (young or subsequent) and not ordinary_only:\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-ordinary_keeps_special_route.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/ordinary_keeps_special_route /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_holds_a_qc_in_its_first_quarter" + ], + "log": "scratch/review/round20-mutation-ordinary_keeps_special_route.log", + "name": "ordinary_keeps_special_route", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-ordinary_keeps_special_route.json" + }, + { + "changes": [ + { + "after": " person,\n person.disability_onset,\n _current_period_start_horizon(person, month),\n ) | _prior_sensitive_years(person, binding)\n", + "before": " person, person.disability_onset, start\n ) | _prior_sensitive_years(person, binding)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round20 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round20 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND20_MUTATION=scratch/review/round20-mutation-fix_reverted.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/fix_reverted /tmp/tbvenv/bin/python scratch/review/run_round20_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_partial_years_after_the_start_stay_open" + ], + "log": "scratch/review/round20-mutation-fix_reverted.log", + "name": "fix_reverted", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "spec_path": "scratch/review/round20-mutation-fix_reverted.json" + } + ], + "round_20_runner_source": "\"\"\"Run named invented-data conformance tests with open-event auditing.\"\"\"\n\nimport hashlib\nimport json\nimport os\nfrom pathlib import Path\nimport sys\n\nCOUNTS = {\"restricted_opens\": 0, \"subprocess.Popen\": 0, \"os.system\": 0}\nBARRED = {\n \"gates.yaml\", \"adjusted_poverty.py\", \"rows.py\",\n \"ssa_trust_fund_interest_rates_2026.json\",\n \"urban2010_cola_comparison.md\", \"urban2010_fra68_comparison.md\",\n \"boomers2004_uniform_cut_comparison.md\", \"minimum_benefits_comparison.md\",\n \"m6_projection_engine.md\", \"mint8_table_user_guide.source.html\",\n \"test_anchor_provenance_erratum.py\",\n \"s0_1_power_results.json\", \"s0_1_source_audit.md\", \"s0_1_power.py\",\n \"test_s0_1_invariants.py\", \"test_s0_1_power.py\",\n \"test_s0_1_thresholds.py\",\n}\n\n\ndef audit(event, arguments):\n if event == \"open\" and isinstance(arguments[0], (str, bytes)):\n path = os.fsdecode(arguments[0])\n name = Path(path).name\n if (\n name in BARRED\n or name.startswith((\"adjusted_poverty.\", \"rows.\"))\n or \"/PolicyEngine/psid-data/\" in path\n or \"/microcosm-launch-evidence/\" in path\n or \"/dynasim-refs/\" in path\n or \"/claude-501/\" in path\n or \"/tests/s0_1/\" in path\n or \"/tests/acola_track/\" in path\n or \"/tests/cola_track_a/\" in path\n or \"/tests/fra68_track/\" in path\n ):\n COUNTS[\"restricted_opens\"] += 1\n raise RuntimeError(path)\n elif event in (\"subprocess.Popen\", \"os.system\"):\n COUNTS[event] += 1\n\n\ndef main():\n for name in (\"POPULACE_DYNAMICS_PSID_DIR\", \"POPULACE_DYNAMICS_EPUF_DIR\"):\n assert os.environ[name] == \"/nonexistent/trackb-round20\"\n assert sys.argv[1:]\n assert all(\n not argument.startswith(\"tests/\") or \".py\" in argument\n for argument in sys.argv[1:]\n )\n sys.addaudithook(audit)\n from populace_dynamics.track_b import insured_status as insured\n\n source_path = Path(insured.__file__)\n original = source_path.read_bytes()\n baseline_path = os.environ.get(\"TRACKB_ROUND16_SOURCE\")\n if baseline_path:\n baseline = Path(baseline_path).read_bytes()\n exec(compile(baseline, str(source_path), \"exec\"), insured.__dict__)\n print(\"BASELINE\", hashlib.sha256(baseline).hexdigest(), flush=True)\n spec_path = os.environ.get(\"TRACKB_ROUND20_MUTATION\")\n if spec_path:\n spec = json.loads(Path(spec_path).read_text())\n assert hashlib.sha256(original).hexdigest() == spec[\"source_sha256\"]\n source = original.decode()\n for change in spec[\"changes\"]:\n assert source.count(change[\"before\"]) == 1, change[\"before\"]\n source = source.replace(change[\"before\"], change[\"after\"], 1)\n exec(compile(source, str(source_path), \"exec\"), insured.__dict__)\n print(\"MUTATION\", spec[\"name\"], flush=True)\n import pytest\n\n try:\n return pytest.main(sys.argv[1:])\n finally:\n assert source_path.read_bytes() == original\n print(\"OPEN_AUDIT\", json.dumps(COUNTS, sort_keys=True), flush=True)\n\n\nif __name__ == \"__main__\":\n raise SystemExit(main())\n", + "round_20_note": "A cloud session ran round 20's 41 mutations at 38a573a8, the final round 20 source and test bytes, against every insured status module, with no restricted open (PR #562 comment 6589941045). The 41 are round 19's 40 and fix_reverted, which restores the start-keeping search's old horizon. All 41 failed a named test.", + "round_20_test_sha256": { + "tests/test_track_b_insured_status_fix_round_20.py": "2c3a62b50c5f7ecbfd465d77731671f949ec534b424cfc97d1c3cee2df8f12c1", + "tests/test_track_b_insured_status_readings.py": "50c07c63bb2723bb7b7351bfe91c7971e3f31fc6ff1cb02e0ec3c8061a27cfee", + "tests/test_track_b_insured_status_fix_round_2.py": "c1d00971949eb7d1f9ac458dfea1b5e47922fb3d0047a50a764e7400f9321835", + "tests/test_track_b_insured_status_fix_round_19.py": "5075e9aa563740106a5e080fa23f4f9d928ebaa2c10e1f4afe575f10c5bd4d0e", + "tests/test_track_b_insured_status_status_stress.py": "f6e96aca3cb607c28f538b088751c1dae7252c4ae8df0837e4e147ab4482deac", + "tests/test_track_b_insured_status_fix_round_18.py": "b4bf594a55df126421950a890f6a089ec18f13bac2ef7a94431af1606d384c1b", + "tests/test_track_b_insured_status_fix_round_17.py": "1f7751a66198a84356bf5c0ea76e12d4bcfbf2181cfbc3e337970dfbe16e5449" + }, + "round_20_replay": "Write round_20_runner_source to scratch/review/run_round20_named.py. For each round_20_mutations record, write name/source_sha256/changes to its spec_path, then execute its exact command at 38a573a8. Mutations apply only in memory.", + "round_20_final_source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2" } From e25078028cf6a0f585878dc1487671e561587cc7 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Mon, 2 Nov 2026 17:25:49 -0500 Subject: [PATCH 30/46] Hold a listed prior on each basis its record allows (#562) DisabilityPeriod records no blindness, and Person.statutory_blindness is current only, so a record doesn't say whether an unflagged prior rested on past blindness (404.130(e), fully insured alone) or on 404.130(b) or (c). The rule held every such prior to the blind test, so a result could rest on a placement only the blind basis allows. _prior_basis now reads the strictest basis some placement allows. Every placement 404.130(b) or (c) allows also passes 404.130(e), so a filling that keeps the prior there speaks for both, and a result none attains refuses by name. A listed prior no placement supports on any basis now refuses by name too, since it rests on credits or facts the record omits. Co-Authored-By: Claude Opus 5.5 --- .../track_b/insured_status.py | 131 ++++++++++++------ 1 file changed, 88 insertions(+), 43 deletions(-) diff --git a/src/populace_dynamics/track_b/insured_status.py b/src/populace_dynamics/track_b/insured_status.py index 868f62291..6486e163f 100644 --- a/src/populace_dynamics/track_b/insured_status.py +++ b/src/populace_dynamics/track_b/insured_status.py @@ -1718,16 +1718,16 @@ def _start_fixed(person, credits, start, month, exit_month): ) -def _prior_passes(person, credits, index, exit_month, **options): +def _prior_passes(person, credits, index, exit_month, *, blind, **options): """Whether a route insures a listed prior's start, with earlier priors. - Past blindness leaves no trace in the record and asks only for fully - insured status (404.130(e)), so an unflagged prior needs that much. + ``blind`` reads the holder as blind then, which asks only for fully + insured status (404.130(e)). """ period = person.prior_disability_periods[index] earlier = replace( person, - statutory_blindness=not period.special_insured, + statutory_blindness=blind, prior_disability_periods=person.prior_disability_periods[:index], ) return _witness( @@ -1741,63 +1741,104 @@ def _prior_passes(person, credits, index, exit_month, **options): def _keeps_priors(person, filling, binding, exit_month): - """Whether one filling lets each binding prior begin where it says. + """Whether one filling lets each binding prior begin on its basis. A flagged prior's holder "were only insured under paragraph (c)" (404.130(d)(1)), so that holder passes a special route and not 404.130(b). """ return all( - _prior_passes(person, filling, index, exit_month) + _prior_passes(person, filling, index, exit_month, blind=blind) and not ( person.prior_disability_periods[index].special_insured and _prior_passes( - person, filling, index, exit_month, ordinary_only=True + person, + filling, + index, + exit_month, + blind=False, + ordinary_only=True, ) ) - for index in binding + for index, blind in binding ) -def _prior_start_binds(person, lower, upper, index, month, exit_month): - """Whether annual placement decides a listed prior's own start. +def _every_placement_begins( + person, lower, index, month, exit_month, *, blind, **options +): + """Whether every annual placement insures a listed prior's start. - A period begins in a quarter its holder was insured (404.320(b)(2), - 404.321(a)), so a prior can force an annual QC into one quarter. A prior - that holds on every placement leaves them all open. One that holds on - none rests on something this record doesn't show, and says nothing about - placement. Otherwise it picks among them. Lower credits speak for every - completion of an UNKNOWN year, and upper credits bound them all. ``every`` - drops earlier priors, so a later prior resting on one counts as picking, - and the search that follows then keeps the fillings it holds on. + Lower credits speak for every completion of an UNKNOWN year. This drops + earlier priors, so a later prior resting on one fails here, and the search + that follows then keeps the fillings it holds on. """ - period = person.prior_disability_periods[index] - flagged = period.special_insured - bare = replace( - person, - statutory_blindness=not flagged, - prior_disability_periods=(), + return _every_placement_passes( + replace( + person, statutory_blindness=blind, prior_disability_periods=() + ), + lower, + person.prior_disability_periods[index].start, + month, + exit_month, + InsuredTest.DISABILITY, + **options, ) - def every(**options): - return _every_placement_passes( - bare, + +def _prior_basis(person, lower, upper, index, month, exit_month): + """Whether past blindness alone can support a listed prior's start. + + A period begins in a quarter its holder was insured (404.320(b)(2), + 404.321(a)). The record doesn't say whether an unflagged prior rested on + past blindness, which asks only for fully insured status (404.130(e)), or + on 404.130(b) or (c), which ask for that and more. A result has to stand + on each basis some placement allows. Every placement 404.130(b) or (c) + allows also passes 404.130(e), so a filling that keeps the prior on them + speaks for both, and they hold the prior wherever a placement meets them. + A flagged prior's holder "were only insured under paragraph (c)" + (404.130(d)(1)), so no placement supports that prior if none passes a + route or all of them pass 404.130(b). A prior no placement supports rests + on credits or facts this record omits, and those could move other results, + so the rule refuses it by name. Upper credits bound every completion of an + UNKNOWN year. + """ + if person.prior_disability_periods[index].special_insured: + if _prior_passes( + person, upper, index, exit_month, blind=False + ) and not _every_placement_begins( + person, lower, - period.start, + index, month, exit_month, - InsuredTest.DISABILITY, - **options, - ) + blind=False, + ordinary_only=True, + ): + return False + else: + for blind in (False, True): + if _prior_passes(person, upper, index, exit_month, blind=blind): + return blind + _refuse( + InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, + "No annual placement supports a listed prior's first insured quarter", + ) - def some(**options): - return _prior_passes(person, upper, index, exit_month, **options) - if not flagged: - return not every() and some() - return ( - some() - and not every(ordinary_only=True) - and not (every() and not some(ordinary_only=True)) +def _prior_start_binds(person, lower, upper, index, month, exit_month, blind): + """Whether annual placement decides a listed prior's start on its basis. + + A prior that holds on every placement leaves them all open, and otherwise + it picks among them. A flagged prior that every placement carries on its + route, short of 404.130(b), holds on every placement. + """ + every = _every_placement_begins( + person, lower, index, month, exit_month, blind=blind + ) + if not person.prior_disability_periods[index].special_insured: + return not every + return not every or _prior_passes( + person, upper, index, exit_month, blind=False, ordinary_only=True ) @@ -1831,7 +1872,7 @@ def _prior_sensitive_years(person, binding): """Years whose annual placement can change a binding prior's start.""" return { year - for index in binding + for index, _ in binding for year in _start_sensitive_years( person, person.prior_disability_periods[index].start, @@ -3203,14 +3244,18 @@ def insured_status( _settle_every_history( person, lower, month, coverage_end_month, decisions, dli ) + bases = tuple( + _prior_basis(person, lower, upper, index, month, coverage_end_month) + for index in range(len(person.prior_disability_periods)) + ) # Every placement attains what the proof above passes, so a prior that # picks among them can't move it. binding = tuple( - index - for index in range(len(person.prior_disability_periods)) + (index, blind) + for index, blind in enumerate(bases) if not current_unknown and _prior_start_binds( - person, lower, upper, index, month, coverage_end_month + person, lower, upper, index, month, coverage_end_month, blind ) ) if binding and unknown: From e2b9390cc6d5784c511888c9663d161593d42044 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Mon, 2 Nov 2026 18:19:24 -0500 Subject: [PATCH 31/46] Test each basis a listed prior can rest on (#562) Round 21's tests, oracle and generators, and the design note so far. basis_worlds replaces fillings_keeping_priors, so each status and date has to hold on every combination of bases a record allows. Five older invented records listed a prior no placement can begin and gained the QCs it needs, and test_unknown_establishment_needs_the_disregard now reaches the proof instead of the new refusal. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 169 ++++++- tests/test_track_b_insured_status.py | 16 +- tests/test_track_b_insured_status_contract.py | 14 +- ...est_track_b_insured_status_fix_round_15.py | 2 + ...est_track_b_insured_status_fix_round_19.py | 56 ++- ...est_track_b_insured_status_fix_round_20.py | 20 +- ...est_track_b_insured_status_fix_round_21.py | 430 ++++++++++++++++++ ...st_track_b_insured_status_status_stress.py | 252 +++++++--- 8 files changed, 847 insertions(+), 112 deletions(-) create mode 100644 tests/test_track_b_insured_status_fix_round_21.py diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index eef1a15c9..67bc53d77 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -1700,7 +1700,9 @@ and computes no payment. 00301.230 makes annual placement flexible, and 404.321(a) gives a period one start. Where placement can move a start, a result stands only if one filling of the years that can move it keeps the start and attains the result. Other - years stay flexible for each status. + years stay flexible for each status. A record doesn't say which route began + an unflagged prior, so that filling has to keep the prior on the strictest + route some placement meets (round 21). - `us:oasdi-insured-subsequent-special-long-period` (`_witness`, `_unknown_prior_joint_shortfall`). Act 223(c)(1)(B)(iii) asks for half the quarters after age 21 with no cap, and 404.130(d)(2) caps the test at 20 of @@ -2563,13 +2565,14 @@ prior listed OBSERVED. A listed prior differs from an unknown one in one way: the record names it, so the search can hold it. `_prior_start_binds` asks whether placement decides a prior's own start. A prior -that holds on every placement leaves them all open. One that holds on none rests -on something this record doesn't show, and says nothing about placement. Past -blindness leaves no trace in the record and asks only for fully insured status -(404.130(e)), so an unflagged prior needs that much. A flagged prior's holder +that holds on every placement leaves them all open. A flagged prior's holder "were only insured under paragraph (c)" (404.130(d)(1)), so that holder passes a special route and not 404.130(b). A prior that every placement carries past -404.130(b) therefore holds on none. +404.130(b) therefore holds on none. At this round the predicate read every +unflagged prior as resting on past blindness, and it let a prior that holds on +none pass. Round 21 replaces both: `_prior_basis` holds an unflagged prior on +404.130(b) or (c) wherever a placement meets them, and a prior no placement +supports refuses by name. Otherwise the prior picks among placements, and the logged first-start reading applies to its start: one filling of the years that can move that start must @@ -2652,11 +2655,12 @@ These tests execute the invariants this round adds: - a start some placement moves stays open, and a start every placement holds stands (`test_a_start_some_placement_moves_stays_open`, `test_a_fixed_start_is_the_onset`); -- `_prior_start_binds` answers true only where placement splits the prior or a - later prior rests on an earlier one +- `_prior_start_binds` answers true only where placement splits the prior on + the basis it holds or a later prior rests on an earlier one (`test_placement_binds_a_prior_only_when_it_splits_them`); - a computed result on a listed prior is the best the prior allows, for each - status, count and date (`check`, `check_no_period`, and their stress tests); + status, count and date, and round 21 asks this of each basis the prior can + rest on (`check`, `check_no_period`, and their stress tests); - a listed prior that placement decides never moves a result it can't reach, and a result no kept filling attains refuses by name (`test_a_listed_prior_can_undercut_the_date`, @@ -2741,8 +2745,7 @@ round: `test_an_unknown_year_refuses_that_later_prior`). `test_a_later_prior_placement_splits_binds` draws pairs of priors. It checks `_prior_passes` on each fixed filling against the oracle, and it checks that - `_prior_start_binds` answers true wherever those fillings split and false - where none holds the prior. + `_prior_start_binds` answers true wherever those fillings split. - `flagged_refuses_every_placement` drops the clause that releases a flagged prior every placement carries. That prior's holder "were only insured under paragraph (c)" (404.130(d)(1)). When every placement passes its route and @@ -2782,7 +2785,7 @@ These tests execute the invariants this round adds: period (`test_an_establishment_counts_no_quarter_of_its_own_period`); - `_prior_passes` on a fixed filling agrees with the oracle for a later prior counted with an earlier one, and `_prior_start_binds` answers true wherever - placement splits the prior and false where no placement holds it + placement splits the prior (`test_a_later_prior_placement_splits_binds`, `test_a_later_prior_on_an_earlier_endpoint_binds`); - a flagged prior that every placement carries on its route, short of 20 of @@ -2790,6 +2793,148 @@ These tests execute the invariants this round adds: (`test_a_special_prior_every_placement_carries_binds_nothing`, `test_an_unknown_year_leaves_a_special_prior_every_placement_carries`). +## Round 21 a listed prior's basis + +Verification class: statutory conformance on invented declarations only. +This correction admits no population, behavioral, payment, or forecast claim. +An independent review of `38a573a8` reported one medium and one low (PR #562 +comment 6589002155). Both ask what a listed prior says about placement. + +### The record doesn't say why a prior began + +A period begins in a quarter its holder was insured (404.320(b)(2), +404.321(a)). `DisabilityPeriod` records no blindness, and +`Person.statutory_blindness` speaks only for the present. An unflagged prior +could rest on past blindness, which asks only for fully insured status +(404.130(e)), or on 404.130(b) or (c), which ask for that and more. `38a573a8` +held every unflagged prior to fully insured status alone. That weakest test +suits a possibility proof, but it let a true status or a date stand where only +the blind reading reaches it. + +An invented person born 1955-02-02 has four QCs in each of 1980 to 1984 and +1989 to 1992, three in 1993, one in 1998, four in each of 1999 to 2002 and three +in 2003, with a listed prior from 1998-01-01 through 1999-12-31. For a January +2008 query, `38a573a8` reported a date last insured of 2008-03-31. + +The arithmetic runs by hand. The 39 QCs before 1998 clear the 21 that fully +insured status asks at the prior's start (the elapsed years 1977 to 1997), so +past blindness leaves the 1998 QC in any quarter. 404.130(b) also asks 20 of 40. +The quarters from 1988Q2 through 1997Q4 hold 19 QCs, so it needs the 1998 QC in +1998Q1. The 40 quarters through 2008Q1 then hold 19 QCs with the period's +quarters counted, and 17 with its exclusion. The 40 quarters through 2007Q4 hold +20. The date falls on 2007-12-31 on 404.130(b) and on 2008-03-31 on past +blindness. With an onset in January 2008, `38a573a8` reported DISABILITY true, +which only past blindness reaches. + +### Each basis the record allows + +404.130(b) and (c) each ask for fully insured status too, so every filling that +begins a prior on them also begins it on past blindness. The rule's results take +the best lawful filling. A filling that begins the prior on the strictest basis +and attains a result therefore proves that result on the other basis too, and a +result no such filling attains differs between them. False results stay false +on any subset of placements. + +`_prior_basis` picks that strictest basis, one prior at a time. It returns false +where some placement meets 404.130(b) or (c), with the earlier priors, and true +where only past blindness can begin the prior. `_prior_start_binds` then asks +whether placement decides the prior on that basis, and `_keeps_priors` tests each +filling on it, so `binding` now pairs each prior with its basis. A result none of +those fillings attains refuses by name and keeps the row's weight +(`test_a_date_only_blindness_reaches_refuses`, +`test_a_status_only_blindness_reaches_refuses`, +`test_that_refusal_keeps_the_row`). Round 19's limits apply unchanged: an UNKNOWN +year with a prior that placement decides refuses +(`test_an_unknown_year_refuses_a_prior_placement_decides`), and a current period +after the prior searches the same fillings +(`test_a_current_period_after_that_prior_refuses`). + +This treats a missing fact. It adds no reading of the law, so it adds no entry to +the register, and the one-filling reading now names the basis. Counts and +assignments come from the strict basis's fillings, while statuses and the date +match on every basis. Two priors whose strict bases no one filling can meet +together refuse, though a weaker basis for one could compute. Refusing keeps the +row. + +### A prior no placement supports + +`38a573a8` also computed a record whose listed prior no placement can begin, +treating that prior as unconstrained. Such a prior rests on credits or facts the +record omits, and those could move other results, so `_prior_basis` now refuses +it by name for every test, with or without an established current period +(`test_a_prior_no_placement_supports_refuses_for_each_test`, +`test_unknown_establishment_refuses_a_prior_no_placement_supports`). A flagged +prior needs a special route on some placement and must stay short of 404.130(b) +on some placement (`test_a_flagged_prior_no_placement_supports_names_why`). Upper +credits speak for the route and lower credits for 404.130(b), so an UNKNOWN year +that could support the prior leaves the decision to placement +(`test_an_unknown_year_can_support_a_prior`, +`test_an_unknown_year_can_leave_a_flagged_prior_short_of_the_ordinary_rule`). + +This changed five older invented records that listed a prior their credits +couldn't begin. Their tests ask about other things, so each record gained the QCs +its prior needs, and each test still reaches its own boundary: round 15's "prior +period year" (`test_an_entitlement_window_cannot_borrow_the_starts_placement`), +`test_unknown_bounds_with_prior_disability_period`, +`test_sam_favorable_disregard_counterexample_one_qc_boundary`, +`test_property_disability_period_exclusion_never_adds_qcs` and +`test_property_subsequent_special_and_dli_monotonic`. Three round 19 tests that +pinned the old answer now pin the refusal. + +### Oracle and generators + +`basis_worlds` replaces `fillings_keeping_priors`. It lists the fillings each +combination of bases allows, strictest first, and drops an empty combination. +`check` and `check_no_period` now require each status and the date on every +combination, the counts on the first, and at least one combination behind any +computed result. `check_every_history` also reads the fillings that keep a prior +on 404.130(b) or (c). `basis_prior_declaration` redraws the record above around +its edge, and `two_basis_declaration` adds a prior with its own basis, in either +order. `test_each_basis_matches_every_placement` compares `_prior_passes`, +`_prior_basis` and `_prior_start_binds` on both bases with every placement of the +drawn records, and that test also checks that each filling passing 404.130(b) or +(c) passes past blindness. + +Refusing a prior no placement supports left 62 percent of +`subsequent_declaration`'s draws refusing, so that generator now places the QCs +its prior needs. It computes on 278 of 400 draws, with 11 refusing for want of +support. +`test_status_stress_candidate_order_changes_nothing` moved from seed 5000019, +which now refuses, to 5000059. + +ROUND21-RESULTS + +These tests execute the invariants this round adds: + +- a computed status, date or result on a listed prior holds on each basis some + placement allows, and otherwise the row refuses by name and keeps its weight + (`check`, `check_no_period`, `test_status_stress_a_prior_on_either_basis`, + `test_status_stress_priors_on_different_bases`, + `test_status_stress_a_current_period_after_either_basis`, + `test_a_date_only_blindness_reaches_refuses`, + `test_that_refusal_keeps_the_row`); +- every filling that passes 404.130(b) or (c) at a prior's start passes past + blindness, and `_prior_basis` and `_prior_passes` agree with every placement on + both bases (`test_each_basis_matches_every_placement`, + `test_a_filling_keeps_a_prior_on_its_own_basis`); +- `_prior_basis` returns false wherever a placement meets 404.130(b) or (c), + including with an earlier prior, and true only where past blindness alone can + begin the prior (`test_each_basis_matches_every_placement`, + `test_a_prior_only_blindness_can_begin_keeps_that_basis`, + `test_a_later_prior_can_rest_on_an_earlier_one_on_either_basis`); +- `_prior_start_binds` on the first prior answers true exactly where some + placement fails its basis, and on a later prior wherever one does + (`test_each_basis_matches_every_placement`, + `test_every_nonblind_placement_binds_nothing`, + `test_one_placement_can_decide_a_nonblind_prior_alone`); +- a prior no placement supports refuses by name for every test, and an UNKNOWN + year that could support it leaves the decision to placement + (`test_a_prior_no_placement_supports_refuses_for_each_test`, + `test_a_flagged_prior_no_placement_supports_names_why`, + `test_unknown_establishment_refuses_a_prior_no_placement_supports`, + `test_an_unknown_year_can_support_a_prior`); +- a flagged prior has one basis (`test_a_flagged_prior_has_one_basis`). + ## Not in scope No real data, population evaluation, baseline claiming hazard, behavioral diff --git a/tests/test_track_b_insured_status.py b/tests/test_track_b_insured_status.py index ab6cd1d7f..e974ffee4 100644 --- a/tests/test_track_b_insured_status.py +++ b/tests/test_track_b_insured_status.py @@ -805,7 +805,12 @@ def test_property_disability_period_exclusion_never_adds_qcs( ), ) month = date(2026, 12, 1) - annual = {start_year: counts[0], start_year + 1: counts[1]} + # Six full years before the prior insure its start on either basis. + annual = { + **dict.fromkeys(range(start_year - 6, start_year), 4), + start_year: counts[0], + start_year + 1: counts[1], + } plain = compute(person, month, annual) excluded = compute(frozen, month, annual) for year in plain.qcs_by_year: @@ -995,12 +1000,13 @@ def test_property_subsequent_special_and_dli_monotonic(year, count): sspa211_provenance=i.EarningsProvenance.OBSERVED, ) month = date(1983, 6, 1) + # Eight QCs from 1971Q3 through 1975Q2 pass the prior's route. lower = { 1970: 1, 1971: 2, 1972: 3, 1973: 2, - 1974: 2, + 1974: 3, 1978: 4, 1979: 1, 1980: 1, @@ -1232,9 +1238,11 @@ def test_sam_favorable_disregard_counterexample_one_qc_boundary(): sspa211_applies=False, sspa211_provenance=i.EarningsProvenance.OBSERVED, ) - counts = {1983: 1, 1984: 4, 1988: 4, 1989: 4, 1992: 4, 1993: 2} + # The 1993 QCs set the boundary, and the 1983 and 1984 QCs pass the prior's + # route at 1985Q4. + counts = {1983: 2, 1984: 4, 1988: 4, 1989: 4, 1992: 4, 1993: 1} below = compute(person, date(1993, 5, 1), counts) - counts[1983] = 2 + counts[1993] = 2 at = compute(person, date(1993, 5, 1), counts) assert not below.disability.insured assert at.disability.insured diff --git a/tests/test_track_b_insured_status_contract.py b/tests/test_track_b_insured_status_contract.py index c4308cd26..556569ca6 100644 --- a/tests/test_track_b_insured_status_contract.py +++ b/tests/test_track_b_insured_status_contract.py @@ -366,8 +366,15 @@ def test_unknown_bounds_with_prior_disability_period(counts): sspa211_provenance=i.EarningsProvenance.OBSERVED, ) month = date(2012, 12, 1) + # Eight QCs before the prior pass its route at 2004Q2. years = history( - person, month, dict(zip(range(2005, 2013), counts, strict=True)) + person, + month, + { + 2002: 4, + 2003: 4, + **dict(zip(range(2005, 2013), counts, strict=True)), + }, ) years[2006] = i.CoverageYear(i.EarningsProvenance.UNKNOWN) for kind in ( @@ -378,8 +385,9 @@ def test_unknown_bounds_with_prior_disability_period(counts): try: result = i.insured_status(person, years, month, test=kind) except i.InsuredConfigurationUnsupported as refusal: - assert ( - refusal.reason is i.InsuredUnsupportedReason.UNKNOWN_EARNINGS + assert refusal.reason in ( + i.InsuredUnsupportedReason.UNKNOWN_EARNINGS, + i.InsuredUnsupportedReason.SUBSEQUENT_LONG_PERIOD, ) continue for count in range(5): diff --git a/tests/test_track_b_insured_status_fix_round_15.py b/tests/test_track_b_insured_status_fix_round_15.py index 4a8b49675..c4e0d1df0 100644 --- a/tests/test_track_b_insured_status_fix_round_15.py +++ b/tests/test_track_b_insured_status_fix_round_15.py @@ -570,6 +570,8 @@ def test_the_date_last_insured_alone_can_refuse_a_moving_start(): ), month=date(2012, 1, 1), counts={ + 1986: 4, + 1987: 4, 1990: 4, 1991: 4, 2000: 4, diff --git a/tests/test_track_b_insured_status_fix_round_19.py b/tests/test_track_b_insured_status_fix_round_19.py index 3c32a0ff7..c2205b874 100644 --- a/tests/test_track_b_insured_status_fix_round_19.py +++ b/tests/test_track_b_insured_status_fix_round_19.py @@ -405,8 +405,10 @@ def test_a_known_absence_keeps_the_status(): def test_unknown_establishment_needs_the_disregard(): # Counting the listed prior reaches back through 1995 for seven of 13, and # the disregard finds three. A period on this record joins that prior in - # any count, so the listed prior alone can't carry the status. + # any count, so the listed prior alone can't carry the status. The 1990 QCs + # give that prior the ten fully insured status asks at its start. annual = { + 1990: 4, 1995: 4, 1996: 2, 2000: 1, @@ -630,11 +632,13 @@ def test_a_prior_every_placement_supports_binds_nothing(): assert result.dli.upper == date(2008, 3, 31) -def test_a_prior_no_placement_supports_stands_as_declared(): - # Nine QCs are required at 1992Q1 and three can fall by then. The record - # doesn't show what insured that start, so it says nothing about placement. +def test_a_prior_no_placement_supports_refuses(): + # Nine QCs are required at 1992Q1 and three can fall by then. The prior + # rests on credits or facts the record omits, and those could move the + # other results. prior = i.DisabilityPeriod(date(1992, 1, 1), date(1992, 12, 31)) - result = _result( + _refused_with( + ASSIGNMENT, _date_person( prior_disability_periods=(prior,), prior_disability_periods_provenance=OBSERVED, @@ -643,7 +647,6 @@ def test_a_prior_no_placement_supports_stands_as_declared(): date(2008, 1, 1), test=DISABILITY, ) - assert result.disability.insured def test_a_later_prior_can_rest_on_an_earlier_one(): @@ -757,25 +760,25 @@ def test_a_special_prior_on_every_placement_binds_nothing(): assert result.fully.insured -def test_a_special_prior_no_placement_supports_stands_as_declared(): +def test_a_special_prior_no_placement_supports_refuses(): # Twenty QCs reach 20 of 40 on every placement, so the holder was never # "only insured" under paragraph (c). - result = _result( + _refused_with( + ASSIGNMENT, _special_person(), _history(1960, 1995, {**SPECIAL_BASE, 1985: 4}), date(1995, 1, 1), ) - assert result.fully.insured -def test_a_special_prior_short_of_its_route_stands_as_declared(): +def test_a_special_prior_short_of_its_route_refuses(): # Seventeen QCs miss the 18 required on every placement. - result = _result( + _refused_with( + ASSIGNMENT, _special_person(), _history(1960, 1995, {**SPECIAL_BASE, 1985: 1}), date(1995, 1, 1), ) - assert result.fully.insured # The worst filling. @@ -841,10 +844,10 @@ def test_the_worst_filling_matches_every_placement( ), (annual, day, kind) -def _lawful_prior(birth, credits, begins, special): +def _lawful_prior(birth, credits, begins, special, blind=True): at = quarter(begins) if not special: - return disability(birth, credits, at, (), True) + return disability(birth, credits, at, (), blind) return ( disability(birth, credits, at, (), False) and recent(usable(credits, at, ()), at, (), 40) < 20 @@ -875,15 +878,22 @@ def test_placement_binds_a_prior_only_when_it_splits_them( sspa211_applies=False, sspa211_provenance=OBSERVED, ) - held = { - _lawful_prior(birth, credits, begins, special) - for credits in placements(annual) - } + month = date(2005, 1, 1) + # A prior rests on the strictest basis some placement allows. + for blind in (False, True): + held = { + _lawful_prior(birth, credits, begins, special, blind) + for credits in placements(annual) + } + if True in held or special: + break credits = _credits(annual) + if True not in held: + with pytest.raises(i.InsuredConfigurationUnsupported): + i._prior_basis(person, credits, credits, 0, month, None) + return + assert i._prior_basis(person, credits, credits, 0, month, None) is blind binds = i._prior_start_binds( - person, credits, credits, 0, date(2005, 1, 1), None + person, credits, credits, 0, month, None, blind ) - if not special: - assert binds is (len(held) == 2), (annual, begins) - elif not binds: - assert len(held) == 1, (annual, begins) + assert binds is (len(held) == 2), (annual, begins) diff --git a/tests/test_track_b_insured_status_fix_round_20.py b/tests/test_track_b_insured_status_fix_round_20.py index d8e09afc1..91bd1d32f 100644 --- a/tests/test_track_b_insured_status_fix_round_20.py +++ b/tests/test_track_b_insured_status_fix_round_20.py @@ -253,8 +253,9 @@ def test_a_later_prior_on_an_earlier_endpoint_binds(): listed, credits, LATER.start, MONTH, None, DISABILITY ) interior = {**credits, 1999: ((1999 * 4 + 1,), 0)} - assert not i._prior_passes(person, interior, 1, None) - assert i._prior_start_binds(person, credits, credits, 1, MONTH, None) + assert not i._prior_passes(person, interior, 1, None, blind=True) + assert i._prior_basis(person, credits, credits, 1, MONTH, None) is True + assert i._prior_start_binds(person, credits, credits, 1, MONTH, None, True) def test_an_unknown_year_refuses_that_later_prior(): @@ -302,14 +303,17 @@ def test_a_later_prior_placement_splits_binds( for credits in placements(annual): expected = _later_holds(DATE_BIRTH, credits, earlier, later) assert ( - i._prior_passes(person, _filling(annual, credits), 1, None) + i._prior_passes( + person, _filling(annual, credits), 1, None, blind=True + ) is expected ), (annual, earlier, later, sorted(credits)) held.add(expected) credits = _credits(annual) - binds = i._prior_start_binds(person, credits, credits, 1, MONTH, None) - assert binds or len(held) == 1, (annual, earlier, later) - assert not binds or True in held, (annual, earlier, later) + binds = i._prior_start_binds( + person, credits, credits, 1, MONTH, None, True + ) + assert binds or held == {True}, (annual, earlier, later) # A special prior every placement carries. @@ -363,5 +367,7 @@ def test_a_special_prior_every_placement_carries_binds_nothing( for credits in placements(annual) } credits = _credits(annual) - binds = i._prior_start_binds(person, credits, credits, 0, MONTH, None) + binds = i._prior_start_binds( + person, credits, credits, 0, MONTH, None, False + ) assert held != {True} or not binds, (annual, begins) diff --git a/tests/test_track_b_insured_status_fix_round_21.py b/tests/test_track_b_insured_status_fix_round_21.py new file mode 100644 index 000000000..f2019aa6a --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_21.py @@ -0,0 +1,430 @@ +"""Round 21: a listed prior's basis, and a prior no placement supports. + +Verification class: statutory conformance on invented declarations; no +population, behavioral or forecast claim. + +A period begins in a quarter its holder was insured (404.320(b)(2), 404.321(a)). +A DisabilityPeriod records no blindness, and Person.statutory_blindness speaks +only for the present, so a record doesn't say whether an unflagged prior rested +on past blindness, which asks only for fully insured status (404.130(e)), or on +404.130(b) or (c), which ask for that and more. A computed result has to stand +on each basis some placement allows. + +Every placement 404.130(b) or (c) allows also passes 404.130(e), so a filling +that keeps the prior on them speaks for both. A result none attains refuses by +name. A prior no placement supports on any basis rests on credits or facts the +record omits, and those could move other results, so it refuses by name too. +""" + +from dataclasses import replace +from datetime import date + +import pytest +from hypothesis import assume, given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as i +from tests.test_track_b_insured_status_fix_round_17 import ( + ASSIGNMENT, + OBSERVED, + _history, + _person, + _refused_with, + _result, +) +from tests.test_track_b_insured_status_fix_round_19 import ( + DATE_ANNUAL, + DATE_BIRTH, + DATE_PRIOR, + SPECIAL_BASE, + UNKNOWN_ESTABLISHMENT, + _credits, + _date_person, + _special_person, + _unknown_year, +) +from tests.test_track_b_insured_status_fix_round_20 import ( + LISTED_PRIOR, + _filling, + _refusal, +) +from tests.test_track_b_insured_status_status_stress import ( + BASIS_PRIOR, + LAST_40, + basis_prior_declaration, + check_no_period, + last_insured, + listed_prior_declaration, + placements, + prior_holds, + quarter, + two_basis_declaration, + two_prior_declaration, +) + +ALL = i.InsuredTest.ALL +FULLY = i.InsuredTest.FULLY +CURRENTLY = i.InsuredTest.CURRENTLY +DISABILITY = i.InsuredTest.DISABILITY +NO_SUPPORT = ( + "No annual placement supports a listed prior's first insured quarter" +) +BIRTH = BASIS_PRIOR["birth"] +ANNUAL = BASIS_PRIOR["annual"] +MONTH = BASIS_PRIOR["month"] +PRIOR = i.DisabilityPeriod(*BASIS_PRIOR["prior"][0]) +# 1985Q1 finds 28 QCs in its 40 quarters. 1996Q1 finds 20 only by counting the +# 1985 to 1989 period and holding the 1996 QC in that quarter. +EARLIER = i.DisabilityPeriod(date(1985, 1, 1), date(1989, 12, 31)) +LATER = i.DisabilityPeriod(date(1996, 1, 1), date(1997, 12, 31)) +LATER_ANNUAL = { + **dict.fromkeys(range(1978, 1985), 4), + 1990: 4, + 1996: 1, +} +# Every placement holds 20 of 40 at the 1998Q1 prior. +OPEN_ANNUAL = { + **dict.fromkeys(range(1985, 1998), 4), + 1998: 1, + **dict.fromkeys(range(1999, 2003), 4), + 2003: 3, +} + + +def _basis_person(*priors, **changes): + values = dict(disability_onset=None) + values.update(changes) + return replace(_person(*(priors or (PRIOR,)), **values), birth_date=BIRTH) + + +def _years(annual=ANNUAL): + return _history(BIRTH.year, MONTH.year, annual) + + +def _basis(person, annual, index=0, month=MONTH): + credits = _credits(annual) + return i._prior_basis(person, credits, credits, index, month, None) + + +# The two bases. + + +def test_the_two_bases_split_the_date(): + # Plain arithmetic: the 1998 QC falls anywhere on past blindness, and in + # 1998Q1 on 404.130(b). The 40 quarters through 2008Q1 hold 20 only with + # that QC later, and 2007Q4 counts the 1998Q1 QC. + every = tuple(placements(ANNUAL)) + blind = [c for c in every if prior_holds(BASIS_PRIOR, c, 0, True)] + nonblind = [c for c in every if prior_holds(BASIS_PRIOR, c, 0, False)] + assert len(blind) == len(every) + assert nonblind + assert all(quarter(PRIOR.start) in credits for credits in nonblind) + + def best(fillings): + return max( + last_insured( + BIRTH, credits, quarter(MONTH), periods, False, False, LAST_40 + ) + for credits in fillings + for periods in (BASIS_PRIOR["prior"], ()) + ) + + assert best(blind) == quarter(date(2008, 1, 1)) + assert best(nonblind) == quarter(date(2007, 10, 1)) + + +@pytest.mark.parametrize("test", (DISABILITY, ALL)) +def test_a_date_only_blindness_reaches_refuses(test): + refused = _refusal(_basis_person(), _years(), MONTH, test=test) + assert refused.reason is ASSIGNMENT + assert refused.detail == LISTED_PRIOR + + +def test_that_refusal_keeps_the_row(): + _refused_with( + ASSIGNMENT, _basis_person(), _years(), MONTH, test=DISABILITY + ) + + +def test_a_status_only_blindness_reaches_refuses(): + # DISABILITY at 2008Q1 needs the same 20 of 40. + refused = _refusal( + _basis_person(disability_onset=MONTH), + _years(), + MONTH, + test=DISABILITY, + ) + assert refused.detail == LISTED_PRIOR + + +def test_a_current_period_after_that_prior_refuses(): + refused = _refusal( + _basis_person( + disability_onset=date(2004, 1, 1), + current_disability_period_established=True, + current_disability_period_end=date(2004, 12, 31), + current_disability_period_end_provenance=OBSERVED, + ), + _years(), + MONTH, + ) + assert refused.reason is ASSIGNMENT + + +def test_an_unknown_year_refuses_a_prior_placement_decides(): + refused = _refusal( + _basis_person(), + _unknown_year(_years(), 2005), + MONTH, + test=DISABILITY, + ) + assert refused.detail == LISTED_PRIOR + + +# Where the bases agree. + + +def test_a_nonblind_filling_that_reaches_the_date_computes(): + # Four 2003 QCs put 20 in the 40 quarters through 2008Q1 with the 1998 QC + # in its first quarter, so 404.130(b) reaches what blindness reaches. + annual = {**ANNUAL, 2003: 4} + result = _result(_basis_person(), _years(annual), MONTH, test=DISABILITY) + assert result.dli.upper == date(2008, 3, 31) + assert check_no_period({**BASIS_PRIOR, "annual": annual}) == "computed" + + +def test_a_prior_only_blindness_can_begin_keeps_that_basis(): + # Fourteen QCs precede 1998Q1, short of 20 of 40 on every placement, and + # a prior beginning there needs 15. The record then implies past blindness. + person = replace( + _person(DATE_PRIOR, disability_onset=None), birth_date=DATE_BIRTH + ) + assert _basis(person, DATE_ANNUAL) is True + + +def test_every_nonblind_placement_binds_nothing(): + person = _basis_person() + credits = _credits(OPEN_ANNUAL) + assert _basis(person, OPEN_ANNUAL) is False + assert not i._prior_start_binds( + person, credits, credits, 0, MONTH, None, False + ) + case = {**BASIS_PRIOR, "annual": OPEN_ANNUAL} + assert check_no_period(case) == "computed" + + +def test_one_placement_can_decide_a_nonblind_prior_alone(): + # Blindness leaves ANNUAL's 1998 QC open on every placement, so only the + # nonblind basis binds. + person = _basis_person() + credits = _credits(ANNUAL) + assert _basis(person, ANNUAL) is False + assert not i._prior_start_binds( + person, credits, credits, 0, MONTH, None, True + ) + assert i._prior_start_binds( + person, credits, credits, 0, MONTH, None, False + ) + + +def test_a_filling_keeps_a_prior_on_its_own_basis(): + person = _basis_person() + first, later = ( + _filling( + ANNUAL, + next( + credits + for credits in placements(ANNUAL) + if (quarter(PRIOR.start) in credits) is wanted + ), + ) + for wanted in (True, False) + ) + assert i._keeps_priors(person, first, ((0, False),), None) + assert i._keeps_priors(person, first, ((0, True),), None) + assert i._keeps_priors(person, later, ((0, True),), None) + assert not i._keeps_priors(person, later, ((0, False),), None) + + +def test_a_later_prior_can_rest_on_an_earlier_one_on_either_basis(): + # Only counting the earlier period puts 20 of 40 within the later prior's + # reach, so its nonblind basis needs that period. + person = _basis_person(EARLIER, LATER) + assert _basis(person, LATER_ANNUAL, 0) is False + assert _basis(person, LATER_ANNUAL, 1) is False + bare = _basis_person(LATER) + assert _basis(bare, LATER_ANNUAL) is True + + +def test_a_flagged_prior_has_one_basis(): + assert _basis(_special_person(), {**SPECIAL_BASE, 1990: 1}) is False + + +# The bases against every placement. + + +@settings(max_examples=60, deadline=None, derandomize=True) +@given( + seed=st.integers(0, 2**32 - 1), + declare=st.sampled_from( + ( + basis_prior_declaration, + two_basis_declaration, + listed_prior_declaration, + two_prior_declaration, + ) + ), +) +def test_each_basis_matches_every_placement(seed, declare): + case = declare(seed) + annual = case["annual"] + every = tuple(placements(annual)) + assume(len(every) <= 96) + person = replace( + _person( + *(i.DisabilityPeriod(*period) for period in case["prior"]), + disability_onset=None, + ), + birth_date=case["birth"], + ) + credits = _credits(annual) + month = case["month"] + for index in range(len(case["prior"])): + held = {} + for blind in (False, True): + held[blind] = [ + prior_holds(case, filling, index, blind) for filling in every + ] + for filling, expected in zip(every, held[blind], strict=True): + assert ( + i._prior_passes( + person, + _filling(annual, filling), + index, + None, + blind=blind, + ) + is expected + ), (case, sorted(filling), index, blind) + # 404.130(b) and (c) ask for fully insured status too. + assert all( + passes or not strict + for strict, passes in zip(held[False], held[True], strict=True) + ), (case, index) + if not any(held[True]): + with pytest.raises(i.InsuredConfigurationUnsupported) as error: + i._prior_basis(person, credits, credits, index, month, None) + assert error.value.detail == NO_SUPPORT + continue + basis = i._prior_basis(person, credits, credits, index, month, None) + assert basis is (not any(held[False])), (case, index) + binds = i._prior_start_binds( + person, credits, credits, index, month, None, basis + ) + assert binds or all(held[basis]), (case, index) + if index == 0: + assert binds is not all(held[basis]), (case, index) + + +# A prior no placement supports. + + +@pytest.mark.parametrize("test", (ALL, FULLY, CURRENTLY, DISABILITY)) +def test_a_prior_no_placement_supports_refuses_for_each_test(test): + # Nine QCs are required at 1992Q1 and three can fall by then. + prior = i.DisabilityPeriod(date(1992, 1, 1), date(1992, 12, 31)) + refused = _refusal( + _date_person( + prior_disability_periods=(prior,), + prior_disability_periods_provenance=OBSERVED, + ), + _history(1961, 2008, DATE_ANNUAL), + date(2008, 1, 1), + test=test, + ) + assert refused.reason is ASSIGNMENT + assert refused.detail == NO_SUPPORT + + +@pytest.mark.parametrize( + "annual", + ( + pytest.param( + {**SPECIAL_BASE, 1985: 4}, id="reaches_the_ordinary_rule" + ), + pytest.param({**SPECIAL_BASE, 1985: 1}, id="short_of_its_route"), + ), +) +def test_a_flagged_prior_no_placement_supports_names_why(annual): + refused = _refusal( + _special_person(), _history(1960, 1995, annual), date(1995, 1, 1) + ) + assert refused.reason is ASSIGNMENT + assert refused.detail == NO_SUPPORT + + +def test_unknown_establishment_refuses_a_prior_no_placement_supports(): + # Later QCs carry FULLY with no period in force, so the proof over UNKNOWN + # periods passes, and only the check can name this prior. + prior = i.DisabilityPeriod(date(1992, 1, 1), date(1992, 12, 31)) + annual = {1991: 2, 1992: 1, **dict.fromkeys(range(1993, 2001), 4)} + refused = _refusal( + _date_person( + prior_disability_periods=(prior,), + prior_disability_periods_provenance=OBSERVED, + **UNKNOWN_ESTABLISHMENT, + ), + _history(1961, 2001, annual), + date(2001, 1, 1), + test=FULLY, + ) + assert refused.detail == NO_SUPPORT + + +def test_an_unknown_year_can_support_a_prior(): + # Three UNKNOWN years could hold the nine QCs that start needs, so the + # record could support it, and placement then decides. + prior = i.DisabilityPeriod(date(1992, 1, 1), date(1992, 12, 31)) + years = _history(1961, 2008, DATE_ANNUAL) + for year in (1985, 1986, 1987): + years = _unknown_year(years, year) + refused = _refusal( + _date_person( + prior_disability_periods=(prior,), + prior_disability_periods_provenance=OBSERVED, + ), + years, + date(2008, 1, 1), + test=DISABILITY, + ) + assert refused.detail == LISTED_PRIOR + + +def test_an_unknown_year_can_carry_a_flagged_prior_past_the_ordinary_rule(): + # Eighteen QCs pass the route on every placement and fall short of 20 of 40, + # and an UNKNOWN 1984 can add four. Upper credits speak for that completion. + annual = {1985: 2, **dict.fromkeys(range(1986, 1990), 4)} + person = _special_person() + credits = _credits(annual) + assert i._every_placement_begins( + person, credits, 0, date(1995, 1, 1), None, blind=False + ) + refused = _refusal( + person, + _unknown_year(_history(1960, 1995, annual), 1984), + date(1995, 1, 1), + test=FULLY, + ) + assert refused.detail == LISTED_PRIOR + + +def test_an_unknown_year_can_leave_a_flagged_prior_short_of_the_ordinary_rule(): + # An UNKNOWN 1985 runs from 16 QCs, short of 20 of 40, to 20. Lower credits + # speak for every completion, so the ordinary rule doesn't rule this out. + refused = _refusal( + _special_person(), + _unknown_year(_history(1960, 1995, SPECIAL_BASE), 1985), + date(1995, 1, 1), + test=FULLY, + ) + assert refused.detail == LISTED_PRIOR diff --git a/tests/test_track_b_insured_status_status_stress.py b/tests/test_track_b_insured_status_status_stress.py index f36109bbc..7a8585455 100644 --- a/tests/test_track_b_insured_status_status_stress.py +++ b/tests/test_track_b_insured_status_status_stress.py @@ -12,8 +12,10 @@ DIB entitlement month, which ends a CURRENTLY window before the onset. A third draws ages 22-30 at onset, where 404.130(c) applies. A fourth declares a special-insured prior after age 31, where 404.130(d) applies. A declared prior -limits the fillings only through its own start (``prior_holds``). No flags, raw -earnings or death are claimed, and UNKNOWN facts appear only in +limits the fillings only through its own start (``prior_holds``), and a record +doesn't say whether an unflagged prior rested on past blindness, so a computed +result has to stand on each basis the record allows (``basis_worlds``). No +flags, raw earnings or death are claimed, and UNKNOWN facts appear only in ``check_unknown_ending`` and ``check_every_history``. Every annual placement and both all-prior treatments are enumerated. A lawful @@ -455,7 +457,10 @@ def under_31_declaration(seed): def subsequent_declaration(seed): """Declare a special-insured prior before 31, and an onset after it. - The special prior opens 404.130(d) at the later onset. + The special prior opens 404.130(d) at the later onset. The QCs before it + give most draws the half of their quarters that its route asks for, short + of 20 of 40, since no placement supports the rest (404.130(d)(1), 404.321(a)). + The prior's own year can hold the last of them, so placement can decide it. """ case = declaration(seed) draw = random.Random(f"subsequent-{seed}") @@ -463,7 +468,17 @@ def subsequent_declaration(seed): birth = date(onset.year - draw.randint(32, 40), 2, 2) begins = date(birth.year + draw.randint(24, 30), 7, 1) ends = date(begins.year + draw.randint(0, 1), 12, 31) + annual = {y: n for y, n in case["annual"].items() if y > begins.year} + attained = quarter(date(birth.year + 21, birth.month, birth.day)) + needed = max(6, (quarter(begins) - attained) // 2) + annual[begins.year] = draw.randint(0, 2) + needed += draw.choice((0, 0, 0, 1)) - annual[begins.year] + for year in range(begins.year - 1, 1977, -1): + annual[year] = min(needed, 4) + needed -= annual[year] + annual = {y: n for y, n in annual.items() if n} case.update(birth=birth, prior=((begins, ends),), special=True) + case.update(annual=annual) return case @@ -505,31 +520,31 @@ def check_diagnostics(case, result, fillings): ), (case, upper, own) -def prior_can_begin(case, credits, periods): +def prior_can_begin(case, credits, periods, blind=True): """404.130(a), (e): even a blind prior begins fully insured. Each prior counts the periods before it or disregards them (404.130(f)). """ return all( any( - disability(case["birth"], credits, quarter(begins), used, True) + disability(case["birth"], credits, quarter(begins), used, blind) for used in (periods[:index], ()) ) for index, (begins, _) in enumerate(periods) ) -def prior_holds(case, credits, index): - """One declared prior's own start on one filling. +def prior_holds(case, credits, index, blind=True): + """One declared prior's own start on one filling, on one basis. - Past blindness leaves no trace in a record, so an unflagged prior needs - only full insurance. A flagged prior's holder "were only insured under - paragraph (c)" (404.130(d)(1)). + An unflagged prior rests on past blindness, which asks only for full + insurance (404.130(e)), or on 404.130(b) or (c). A flagged prior's holder + "were only insured under paragraph (c)" (404.130(d)(1)). """ at = quarter(case["prior"][index][0]) if not case.get("special"): return any( - disability(case["birth"], credits, at, used, True) + disability(case["birth"], credits, at, used, blind) for used in (case["prior"][:index], ()) ) return ( @@ -538,19 +553,31 @@ def prior_holds(case, credits, index): ) -def fillings_keeping_priors(case, fillings): - """The fillings the declared priors allow. +def basis_worlds(case, fillings): + """The fillings each basis of the declared priors allows, strictest first. - A prior no filling supports rests on something the record doesn't show, - and says nothing about placement. + Past blindness leaves no trace in a record, so each unflagged prior can + rest on either basis. The first world is the strictest with a filling, and + a prior no filling supports on any basis leaves no world. """ - for index in range(len(case["prior"])): - fillings = [ + count = len(case["prior"]) + bases = ( + ((False,) * count,) + if case.get("special") + else tuple(product((False, True), repeat=count)) + ) + worlds = ( + [ filling for filling in fillings - if prior_holds(case, filling[7], index) - ] or fillings - return fillings + if all( + prior_holds(case, filling[7], index, blind) + for index, blind in enumerate(basis) + ) + ] + for basis in bases + ) + return [world for world in worlds if world] def check(case): @@ -565,23 +592,30 @@ def check(case): except InvalidFamilyInput as error: assert not any(worlds), (case, error) return "invalid" - worlds = tuple(fillings_keeping_priors(case, found) for found in worlds) actual = tuple( getattr(result, name).insured for name in ("fully", "currently", "disability") ) start = quarter(result.current_disability_period_start) - for fillings in worlds: - assert fillings, (case, "computed an impossible start", result) - expected = tuple( - any(filling[index] for filling in fillings) for index in (1, 2, 3) - ) - assert actual == expected, (case, actual, expected, result) - for index, insured in enumerate(actual, 1): - assert not insured or any( - filling[0] == start and filling[index] for filling in fillings - ), (case, actual, start, fillings) - check_diagnostics(case, result, fillings) + for found in worlds: + bases = basis_worlds(case, found) + assert bases, (case, "computed an impossible start", result) + for fillings in bases: + expected = tuple( + any(filling[index] for filling in fillings) + for index in (1, 2, 3) + ) + assert actual == expected, (case, actual, expected, result) + for index, insured in enumerate(actual, 1): + assert not insured or any( + filling[0] == start and filling[index] + for filling in fillings + ), (case, actual, start, fillings) + upper = result.dli.upper + assert (None if upper is None else quarter(upper)) == max( + filling[6] for filling in fillings if filling[0] == start + ), (case, upper, fillings) + check_diagnostics(case, result, bases[0]) return "computed" @@ -652,24 +686,28 @@ def check_no_period(case): except rule.InsuredConfigurationUnsupported: return "refused" for reading in READINGS if case.get("special") else READINGS[:1]: - fillings = fillings_keeping_priors( - case, no_period_fillings(case, reading) - ) - for name, index in (("fully", 1), ("currently", 2), ("disability", 3)): - assert getattr(result, name).insured == any( - filling[index] for filling in fillings - ), (case, name, reading, result) + bases = basis_worlds(case, no_period_fillings(case, reading)) + assert bases, (case, "computed a prior no filling supports", result) + for fillings in bases: + for name, index in ( + ("fully", 1), + ("currently", 2), + ("disability", 3), + ): + assert getattr(result, name).insured == any( + filling[index] for filling in fillings + ), (case, name, reading, result) + upper = result.dli.upper + assert (None if upper is None else quarter(upper)) == max( + (filling[6] for filling in fillings if filling[6] is not None), + default=None, + ), (case, reading, upper) for name, position in (("fully", 4), ("currently", 5)): decision = getattr(result, name) count = decision.qc_count_upper assert (decision.insured, count - decision.required, count) == max( - filling[position] for filling in fillings + filling[position] for filling in bases[0] ), (case, name, reading, result) - upper = result.dli.upper - assert (None if upper is None else quarter(upper)) == max( - (filling[6] for filling in fillings if filling[6] is not None), - default=None, - ), (case, reading, upper) return "computed" @@ -931,28 +969,52 @@ def check_every_history( lower = None if result.dli is None else result.dli.lower for added in ((),) if open_period else ((), *added_priors(case)): for ending in endings: - held = history_fillings( + kept = history_fillings( case, added, start, ending, dated=lower is not None ) - if not held: - continue - found = (case, added, ending, result) - assert ( - fully is None - or not fully.insured - or any(filling[1] for filling in held) - ), found - assert ( - currently is None - or not currently.insured - or any(filling[2] for filling in held) - ), found - assert lower is None or quarter(lower) <= max( - -1 if filling[6] is None else filling[6] for filling in held - ), found + nonblind = [ + filling + for filling in kept + if prior_can_begin(case, filling[7], added, blind=False) + ] + for held in filter(None, (kept, nonblind)): + found = (case, added, ending, result) + assert ( + fully is None + or not fully.insured + or any(filling[1] for filling in held) + ), found + assert ( + currently is None + or not currently.insured + or any(filling[2] for filling in held) + ), found + assert lower is None or quarter(lower) <= max( + -1 if filling[6] is None else filling[6] + for filling in held + ), found return "computed" +# A prior from 1998Q1 finds 19 QCs from 1988Q2 through 1997Q4, so 404.130(b) +# holds the 1998 QC in that quarter, while past blindness leaves it open. The 40 +# quarters through 2008Q1 reach 20 only with that QC later. +BASIS_PRIOR = { + "birth": date(1955, 2, 2), + "onset": date(2008, 1, 1), + "ending": date(2008, 3, 31), + "month": date(2008, 1, 1), + "blind": False, + "prior": ((date(1998, 1, 1), date(1999, 12, 31)),), + "annual": { + **dict.fromkeys(range(1980, 1985), 4), + **dict.fromkeys(range(1989, 1993), 4), + 1993: 3, + 1998: 1, + **dict.fromkeys(range(1999, 2003), 4), + 2003: 3, + }, +} # 18 of 37 elapsed quarters pass the route at 1990Q2, and 20 of 40 pass the # ordinary rule. SPECIAL_PRIOR = { @@ -1021,6 +1083,41 @@ def two_prior_declaration(seed): return {**case, "prior": (earlier, *case["prior"])} +def basis_prior_declaration(seed): + """A record whose nonblind prior can hold a QC past blindness leaves open. + + The 1998Q1 prior passes 404.130(e) on every placement, and 404.130(b) only + with 20 QCs in its 40 quarters. Each draw keeps the 1990s record near that + edge, and moves the 40 quarters through the query around their own. + """ + draw = random.Random(f"basis-{seed}") + month = date(draw.randint(2007, 2009), draw.choice((1, 4, 7, 10)), 1) + annual = { + **BASIS_PRIOR["annual"], + 1993: draw.randint(2, 4), + 1998: draw.randint(1, 3), + 2003: draw.randint(2, 4), + } + case = {**BASIS_PRIOR, "month": month, "annual": annual} + return {**case, "onset": month, "ending": quarter_end(quarter(month))} + + +def two_basis_declaration(seed): + """The same record after a prior with its own basis. + + A 1984Q1 prior passes 404.130(c) on 17 QCs. A 1986Q2 prior falls past age + 31, so with 1980's QCs gone it finds 16 of 40 and past blindness alone can + begin it. The two priors can rest on different bases in either order. + """ + case = basis_prior_declaration(seed) + if random.Random(f"two-basis-{seed}").random() < 0.5: + first = (date(1984, 1, 1), date(1984, 12, 31)) + return {**case, "prior": (first, *case["prior"])} + first = (date(1986, 4, 1), date(1986, 12, 31)) + annual = {year: n for year, n in case["annual"].items() if year != 1980} + return {**case, "annual": annual, "prior": (first, *case["prior"])} + + def special_prior_declaration(seed): """A flagged prior whose route and ordinary rule both turn on 1990.""" draw = random.Random(seed) @@ -1042,7 +1139,7 @@ def test_status_stress_year_counts_follow_the_returned_filling(seed): assert check(declaration(seed)) == "computed" -@pytest.mark.parametrize("seed", (5000005, 5000019)) +@pytest.mark.parametrize("seed", (5000005, 5000059)) def test_status_stress_candidate_order_changes_nothing(seed, monkeypatch): forward = public(declaration(seed)) candidates = rule._assignment_candidates @@ -1261,6 +1358,35 @@ def test_status_stress_a_prior_with_no_current_period(seed): check_no_period(two_prior_declaration(seed)) +def test_status_stress_a_nonblind_prior_undercuts_the_date(): + assert check_no_period(BASIS_PRIOR) == "refused" + + +@settings(max_examples=30, deadline=None, derandomize=True) +@given(seed=st.integers(0, 2**32 - 1)) +def test_status_stress_a_prior_on_either_basis(seed): + check_no_period(basis_prior_declaration(seed)) + + +@settings(max_examples=30, deadline=None, derandomize=True) +@given(seed=st.integers(0, 2**32 - 1)) +def test_status_stress_a_current_period_after_either_basis(seed): + case = basis_prior_declaration(seed) + check( + { + **case, + "onset": date(2004, 1, 15), + "ending": date(2004, 12, 31), + } + ) + + +@settings(max_examples=30, deadline=None, derandomize=True) +@given(seed=st.integers(0, 2**32 - 1)) +def test_status_stress_priors_on_different_bases(seed): + check_no_period(two_basis_declaration(seed)) + + @settings(max_examples=30, deadline=None, derandomize=True) @given(seed=st.integers(0, 2**32 - 1)) def test_status_stress_a_flagged_prior_at_its_edge(seed): From 8ea25a8f006b1faa56b04c0b7dbdd22a97361146 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Mon, 2 Nov 2026 18:43:52 -0500 Subject: [PATCH 32/46] Record round 21's wide search and first mutation pass (#562) Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 32 ++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index 67bc53d77..674bae3d3 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -2864,12 +2864,14 @@ record omits, and those could move other results, so `_prior_basis` now refuses it by name for every test, with or without an established current period (`test_a_prior_no_placement_supports_refuses_for_each_test`, `test_unknown_establishment_refuses_a_prior_no_placement_supports`). A flagged -prior needs a special route on some placement and must stay short of 404.130(b) -on some placement (`test_a_flagged_prior_no_placement_supports_names_why`). Upper -credits speak for the route and lower credits for 404.130(b), so an UNKNOWN year -that could support the prior leaves the decision to placement +prior's holder passed a special route and not 404.130(b), so that prior refuses +this way if no placement passes either or every placement passes 404.130(b) +(`test_a_flagged_prior_no_placement_supports_names_why`). Upper credits speak for +the first and lower credits for the second, so an UNKNOWN year that could support +the prior leaves the decision to placement (`test_an_unknown_year_can_support_a_prior`, -`test_an_unknown_year_can_leave_a_flagged_prior_short_of_the_ordinary_rule`). +`test_an_unknown_year_can_leave_a_flagged_prior_short_of_the_ordinary_rule`, +`test_an_unknown_year_can_carry_a_flagged_prior_past_the_ordinary_rule`). This changed five older invented records that listed a prior their credits couldn't begin. Their tests ask about other things, so each record gained the QCs @@ -2902,7 +2904,25 @@ support. `test_status_stress_candidate_order_changes_nothing` moved from seed 5000019, which now refuses, to 5000059. -ROUND21-RESULTS +The wide search drew 150 fresh seeds for each of eight checks on +`basis_prior_declaration`, that record with a current period, +`two_basis_declaration`, `listed_prior_declaration` and +`two_prior_declaration` (each with and without a current period) and +`special_prior_declaration`, plus 150 draws each from `declaration` and +`subsequent_declaration`, skipping 224 draws with more than 96 placements. All +1,276 checks held: 884 computed, 286 refused by name and 106 raised +`InvalidFamilyInput`. + +The list of mutations (`scratch/review/round21_mutate.py`) re-derives round 20's +41 at this round's source, less `unflagged_refuses_unsupported_prior`, whose +branch the rule no longer has, and adds 17 of this round's own. A first pass of +all 57 through rounds 19 to 21 ran with no restricted open, and 54 failed a named +test. Round 2's `test_unknown_period_status_and_dli_bounds_contain_concrete_fillings` +kills `date_tested_at_query`. `proof_keeps_listed_priors` survived because +`test_unknown_establishment_needs_the_disregard` had begun to pass on this +round's new refusal, so that record gained the QCs its prior needs and reaches +the proof again. `test_an_unknown_year_can_carry_a_flagged_prior_past_the_ordinary_rule` +now kills `binds_flag_on_lower_credits`. These tests execute the invariants this round adds: From d1af036694867d64e32bbf1e76f30497ff6310c9 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Mon, 2 Nov 2026 18:47:14 -0500 Subject: [PATCH 33/46] Pin the frozen exit on a prior's basis (#562) Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 3 ++- tests/README-tiers.md | 4 ++-- tests/test_track_b_insured_status_fix_round_21.py | 13 +++++++++++++ tests/tier_counts.json | 2 +- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index 674bae3d3..81f0d1ddc 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -2847,7 +2847,8 @@ those fillings attains refuses by name and keeps the row's weight year with a prior that placement decides refuses (`test_an_unknown_year_refuses_a_prior_placement_decides`), and a current period after the prior searches the same fillings -(`test_a_current_period_after_that_prior_refuses`). +(`test_a_current_period_after_that_prior_refuses`). A frozen exit reaches the same +refusal (`test_a_frozen_exit_after_that_prior_refuses`). This treats a missing fact. It adds no reading of the law, so it adds no entry to the register, and the one-filling reading now names the basis. Counts and diff --git a/tests/README-tiers.md b/tests/README-tiers.md index d3dfa2045..d5eb489b7 100644 --- a/tests/README-tiers.md +++ b/tests/README-tiers.md @@ -39,9 +39,9 @@ pytest --collect-only -q -m oracle_policyengine | tail -1 | Tier | Tests at HEAD | |---|---:| -| `unit` | 25,425 | +| `unit` | 25,426 | | `artifact` | 4,271 | | `integration_psid` | 1,471 | | `reproduction_legacy` | 520 | | `oracle_policyengine` | 337 | -| **Total** | **32,024** | +| **Total** | **32,025** | diff --git a/tests/test_track_b_insured_status_fix_round_21.py b/tests/test_track_b_insured_status_fix_round_21.py index f2019aa6a..8deb4e37b 100644 --- a/tests/test_track_b_insured_status_fix_round_21.py +++ b/tests/test_track_b_insured_status_fix_round_21.py @@ -171,6 +171,19 @@ def test_a_current_period_after_that_prior_refuses(): assert refused.reason is ASSIGNMENT +def test_a_frozen_exit_after_that_prior_refuses(): + # An exit keeps the credits through 2003, and the date past it still turns + # on where the prior puts the 1998 QC. + refused = _refusal( + _basis_person(), + _history(BIRTH.year, 2003, ANNUAL), + date(2027, 1, 1), + test=DISABILITY, + coverage_end_month=date(2003, 12, 1), + ) + assert refused.detail == LISTED_PRIOR + + def test_an_unknown_year_refuses_a_prior_placement_decides(): refused = _refusal( _basis_person(), diff --git a/tests/tier_counts.json b/tests/tier_counts.json index dd008c718..f176c65bb 100644 --- a/tests/tier_counts.json +++ b/tests/tier_counts.json @@ -1,7 +1,7 @@ { "schema_version": 1, "counts": { - "unit": 25425, + "unit": 25426, "artifact": 4271, "integration_psid": 1471, "reproduction_legacy": 520, From fbfb08bb7965837f24e17aebb7907093479bb172 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Mon, 2 Nov 2026 18:58:43 -0500 Subject: [PATCH 34/46] Keep the moving-start test on its own refusal (#562) test_the_date_last_insured_alone_can_refuse_a_moving_start had begun to pass on the new no-support refusal, since its 17 QCs couldn't begin its prior. Its record now gives that prior the 18 it needs on every placement and still moves the current start, and the test pins the refusal's detail. The design note records the log that found it. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 17 ++++++++++++++++- .../test_track_b_insured_status_fix_round_15.py | 15 ++++++++++----- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index 81f0d1ddc..875188642 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -2874,10 +2874,12 @@ the prior leaves the decision to placement `test_an_unknown_year_can_leave_a_flagged_prior_short_of_the_ordinary_rule`, `test_an_unknown_year_can_carry_a_flagged_prior_past_the_ordinary_rule`). -This changed five older invented records that listed a prior their credits +This changed six older invented records that listed a prior their credits couldn't begin. Their tests ask about other things, so each record gained the QCs its prior needs, and each test still reaches its own boundary: round 15's "prior period year" (`test_an_entitlement_window_cannot_borrow_the_starts_placement`), +`test_the_date_last_insured_alone_can_refuse_a_moving_start`, which also gave up a +2008 QC so the current start still moves, `test_unknown_bounds_with_prior_disability_period`, `test_sam_favorable_disregard_counterexample_one_qc_boundary`, `test_property_disability_period_exclusion_never_adds_qcs` and @@ -2925,6 +2927,19 @@ round's new refusal, so that record gained the QCs its prior needs and reaches the proof again. `test_an_unknown_year_can_carry_a_flagged_prior_past_the_ordinary_rule` now kills `binds_flag_on_lower_credits`. +A log of every refusal `_prior_basis` raised, across the insured status modules +other than the stress module, then found one more test resting on the new refusal: +`test_the_date_last_insured_alone_can_refuse_a_moving_start`. Its new record +reaches the moving start again, and the test now pins that refusal's detail. The +list takes round 15's five mutants of that path, re-derived at this source, for +62 in all. Through round 15's module alone all five fail, four of them first on +this test and `remove_first_start_check` first on +`test_no_filling_carries_the_start_and_the_status_together`. The log's other +entries are the tests that pin this refusal, +`test_placement_binds_a_prior_only_when_it_splits_them`, which calls `_prior_basis` +directly, and `test_classification_oracle_prior_and_unknown_completions`, which +checks only that a row and its weight survive. + These tests execute the invariants this round adds: - a computed status, date or result on a listed prior holds on each basis some diff --git a/tests/test_track_b_insured_status_fix_round_15.py b/tests/test_track_b_insured_status_fix_round_15.py index c4e0d1df0..a68b1e519 100644 --- a/tests/test_track_b_insured_status_fix_round_15.py +++ b/tests/test_track_b_insured_status_fix_round_15.py @@ -492,7 +492,11 @@ def test_blind_aggregate_decides_below_six_ordinary_qcs(amount, refused): def test_the_date_last_insured_alone_can_refuse_a_moving_start(): - """DISABILITY never reads the period, so only the date can differ.""" + """DISABILITY never reads the period, so only the date can differ. + + The QCs through 2012 give the prior the 18 fully insured status asks at + its start on every placement, so only the current start can refuse. + """ person = _person( birth=date(1973, 2, 2), disability_onset=date(2015, 5, 15), @@ -503,7 +507,8 @@ def test_the_date_last_insured_alone_can_refuse_a_moving_start(): ) month = date(2022, 1, 1) counts = { - 2008: 2, + 2000: 3, + 2008: 1, 2009: 2, 2010: 4, 2011: 4, @@ -514,9 +519,9 @@ def test_the_date_last_insured_alone_can_refuse_a_moving_start(): 2016: 4, } years = history(person, month, counts) - assert _reason(person, years, month, test=i.InsuredTest.DISABILITY) is ( - ASSIGNMENT - ) + row = _row(person, years, month, test=i.InsuredTest.DISABILITY) + assert row.unsupported.reason is ASSIGNMENT + assert row.unsupported.detail.startswith("First insured start depends") # An entitlement month ends a currently insured window in a year before the From f37f7f797db8eee3c326c48a8385a5cf7dfba1ce Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Mon, 2 Nov 2026 19:37:49 -0500 Subject: [PATCH 35/46] Cap the subsequent generator and keep split seeds on their refusal (#562) subsequent_declaration had grown to six partial years, and the oracle lists every placement, so one draw could hold the stress module for an hour. It now keeps declaration's limit of four, and the module runs in 21 minutes on one process. Ten of the 13 SPLIT_SEEDS had begun to pass on the new no-support refusal. The tuple now holds seeds on which the oracle shows no filling with both the earliest start and the best status or date, and the test pins the moving start's detail. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 11 +++++-- ...st_track_b_insured_status_status_stress.py | 32 +++++++++++-------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index 875188642..af4eab0ee 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -2902,8 +2902,9 @@ drawn records, and that test also checks that each filling passing 404.130(b) or Refusing a prior no placement supports left 62 percent of `subsequent_declaration`'s draws refusing, so that generator now places the QCs -its prior needs. It computes on 278 of 400 draws, with 11 refusing for want of -support. +its prior needs and keeps `declaration`'s limit of four partial years, because +the oracle lists every placement. It computes on 285 of 400 draws, with 11 +refusing for want of support. `test_status_stress_candidate_order_changes_nothing` moved from seed 5000019, which now refuses, to 5000059. @@ -2938,7 +2939,11 @@ this test and `remove_first_start_check` first on entries are the tests that pin this refusal, `test_placement_binds_a_prior_only_when_it_splits_them`, which calls `_prior_basis` directly, and `test_classification_oracle_prior_and_unknown_completions`, which -checks only that a row and its weight survive. +checks only that a row and its weight survive. Over the stress tests that expect a +refusal, the log found ten of `test_status_stress_refuses_a_start_no_filling_supports`'s +13 seeds refusing for want of support. That test now draws 13 seeds on which the +oracle shows no filling with both the earliest start and the best status or date, +and it pins the moving start's detail. These tests execute the invariants this round adds: diff --git a/tests/test_track_b_insured_status_status_stress.py b/tests/test_track_b_insured_status_status_stress.py index 7a8585455..bdae0e1da 100644 --- a/tests/test_track_b_insured_status_status_stress.py +++ b/tests/test_track_b_insured_status_status_stress.py @@ -42,22 +42,23 @@ from populace_dynamics.track_b import insured_status as rule from populace_dynamics.track_b.gross_benefits import InvalidFamilyInput -# Seeds whose first start moved with placement. Round 14 answered each one -# from a start and a status that no single filling supports. +# Seeds whose first start moves with placement, where no filling carries both +# the earliest start and the best status or date. Round 14 answered such a +# record from a start and a result that no single filling supports. SPLIT_SEEDS = ( - 102037, - 102202, - 103045, - 103702, - 105793, - 109597, - 110777, - 203310, - 207027, + 109307, + 109493, + 203503, + 203620, + 203761, + 205457, + 207461, 207682, - 209481, - 209505, + 208179, + 210817, 212010, + 213380, + 213897, ) @@ -477,6 +478,10 @@ def subsequent_declaration(seed): annual[year] = min(needed, 4) needed -= annual[year] annual = {y: n for y, n in annual.items() if n} + # The oracle lists every placement, so keep declaration's limit, and the + # years around the prior. + for credited in [y for y in sorted(annual) if annual[y] < 4][4:]: + annual[credited] = 4 case.update(birth=birth, prior=((begins, ends),), special=True) case.update(annual=annual) return case @@ -1167,6 +1172,7 @@ def test_status_stress_refuses_a_start_no_filling_supports(seed): error.value.reason is rule.InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY ) + assert error.value.detail.startswith("First insured start depends") @settings(max_examples=120, deadline=None, derandomize=True) From aa53bfd4acedbe68f3067f075ada997e49afc900 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Mon, 2 Nov 2026 22:49:57 -0500 Subject: [PATCH 36/46] Record round 21's 62 cloud mutation kills (#562) Cloud brief 6122 ran round 21's 62 mutations at f37f7f79 through every insured status module. All 62 failed a named test with no restricted open (PR #562 comment 6594394873). round_21_mutations keeps the records in the mutate list's order, with the runner, the test hashes and the replay. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 4 + .../track_b_insured_status_mutations.json | 1382 ++++++++++++++++- 2 files changed, 1385 insertions(+), 1 deletion(-) diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index af4eab0ee..0d3bd28a6 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -2945,6 +2945,10 @@ refusal, the log found ten of `test_status_stress_refuses_a_start_no_filling_sup oracle shows no filling with both the earliest start and the best status or date, and it pins the moving start's detail. +A cloud session then ran all 62 at `f37f7f79`, through every insured status +module. All 62 failed a named test, with no restricted open +(`round_21_mutations`, PR #562 comment 6594394873). + These tests execute the invariants this round adds: - a computed status, date or result on a listed prior holds on each basis some diff --git a/docs/design/track_b_insured_status_mutations.json b/docs/design/track_b_insured_status_mutations.json index cd16c5bf4..fcec21056 100644 --- a/docs/design/track_b_insured_status_mutations.json +++ b/docs/design/track_b_insured_status_mutations.json @@ -8379,5 +8379,1385 @@ "tests/test_track_b_insured_status_fix_round_17.py": "1f7751a66198a84356bf5c0ea76e12d4bcfbf2181cfbc3e337970dfbe16e5449" }, "round_20_replay": "Write round_20_runner_source to scratch/review/run_round20_named.py. For each round_20_mutations record, write name/source_sha256/changes to its spec_path, then execute its exact command at 38a573a8. Mutations apply only in memory.", - "round_20_final_source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2" + "round_20_final_source_sha256": "ce068b9b7842cd1ffc97b2dd023f04f7b7d98bd2256620248a774e25f348f0d2", + "round_21_mutations": [ + { + "changes": [ + { + "after": " chosen = vacant[:count]\n", + "before": " chosen = vacant[-count:] if year == at.year else vacant[:count]\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-worst_always_early.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/worst_always_early /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_date_only_blindness_reaches_refuses[InsuredTest.DISABILITY]" + ], + "log": "scratch/review/round21-mutation-worst_always_early.log", + "name": "worst_always_early", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-worst_always_early.json" + }, + { + "changes": [ + { + "after": " chosen = vacant[-count:]\n", + "before": " chosen = vacant[-count:] if year == at.year else vacant[:count]\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-worst_always_late.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/worst_always_late /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_a_later_prior_on_an_earlier_endpoint_binds" + ], + "log": "scratch/review/round21-mutation-worst_always_late.log", + "name": "worst_always_late", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-worst_always_late.json" + }, + { + "changes": [ + { + "after": " if _witness(\n person,\n lower,\n person.disability_onset,\n coverage_end_month,\n InsuredTest.DISABILITY,\n )[0]:\n lo_start = hi_start = person.disability_onset\n", + "before": " if _start_fixed(\n person,\n lower,\n person.disability_onset,\n month,\n coverage_end_month,\n ):\n lo_start = hi_start = person.disability_onset\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-start_on_favorable_placement.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/start_on_favorable_placement /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_status_on_every_placement_computes" + ], + "log": "scratch/review/round21-mutation-start_on_favorable_placement.log", + "name": "start_on_favorable_placement", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-start_on_favorable_placement.json" + }, + { + "changes": [ + { + "after": "", + "before": " if prior_unknown or current_unknown:\n _settle_every_history(\n person, lower, month, coverage_end_month, decisions, dli\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-no_universal_proof.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/no_universal_proof /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_date[known_end]" + ], + "log": "scratch/review/round21-mutation-no_universal_proof.log", + "name": "no_universal_proof", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-no_universal_proof.json" + }, + { + "changes": [ + { + "after": " if prior_unknown:\n _settle_every_history(", + "before": " if prior_unknown or current_unknown:\n _settle_every_history(" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-proof_skips_open_period.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/proof_skips_open_period /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_unknown_establishment_alone_refuses[InsuredTest.ALL]" + ], + "log": "scratch/review/round21-mutation-proof_skips_open_period.log", + "name": "proof_skips_open_period", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-proof_skips_open_period.json" + }, + { + "changes": [ + { + "after": " if current_unknown:\n _settle_every_history(", + "before": " if prior_unknown or current_unknown:\n _settle_every_history(" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-proof_skips_unknown_priors.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/proof_skips_unknown_priors /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_date[known_end]" + ], + "log": "scratch/review/round21-mutation-proof_skips_unknown_priors.log", + "name": "proof_skips_unknown_priors", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-proof_skips_unknown_priors.json" + }, + { + "changes": [ + { + "after": " _settle_every_history(\n person, upper, month,", + "before": " _settle_every_history(\n person, lower, month," + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-proof_on_upper_credits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/proof_on_upper_credits /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_date[unknown_year]" + ], + "log": "scratch/review/round21-mutation-proof_on_upper_credits.log", + "name": "proof_on_upper_credits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-proof_on_upper_credits.json" + }, + { + "changes": [ + { + "after": " if (\n decision is not None\n and False\n and not _every_placement_passes(\n", + "before": " if (\n decision is not None\n and decision.insured\n and not _every_placement_passes(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-proof_skips_statuses.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/proof_skips_statuses /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_status[first_day-InsuredTest.ALL]" + ], + "log": "scratch/review/round21-mutation-proof_skips_statuses.log", + "name": "proof_skips_statuses", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-proof_skips_statuses.json" + }, + { + "changes": [ + { + "after": " if (\n dli is not None\n and False\n and not _every_placement_passes(\n", + "before": " if (\n dli is not None\n and dli.lower is not None\n and not _every_placement_passes(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-proof_skips_the_date.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/proof_skips_the_date /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_date[known_end]" + ], + "log": "scratch/review/round21-mutation-proof_skips_the_date.log", + "name": "proof_skips_the_date", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-proof_skips_the_date.json" + }, + { + "changes": [ + { + "after": " month,\n", + "before": " decision.qualifying_quarter,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-status_tested_at_query.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/status_tested_at_query /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_status_stands_at_the_quarter_it_reports" + ], + "log": "scratch/review/round21-mutation-status_tested_at_query.log", + "name": "status_tested_at_query", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-status_tested_at_query.json" + }, + { + "changes": [ + { + "after": " month,\n", + "before": " _qdate(_qid(dli.lower)),\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-date_tested_at_query.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/date_tested_at_query /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_2.py::test_unknown_period_status_and_dli_bounds_contain_concrete_fillings" + ], + "log": "scratch/review/round21-mutation-date_tested_at_query.log", + "name": "date_tested_at_query", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-date_tested_at_query.json" + }, + { + "changes": [ + { + "after": " bare = person\n for kind, decision", + "before": " bare = replace(person, prior_disability_periods=())\n for kind, decision" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-proof_keeps_listed_priors.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/proof_keeps_listed_priors /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_unknown_establishment_needs_the_disregard" + ], + "log": "scratch/review/round21-mutation-proof_keeps_listed_priors.log", + "name": "proof_keeps_listed_priors", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-proof_keeps_listed_priors.json" + }, + { + "changes": [ + { + "after": " if False\n", + "before": " if not current_unknown\n and _prior_start_binds(\n person, lower, upper, index, month, coverage_end_month, blind\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-no_listed_prior_check.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/no_listed_prior_check /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_date_only_blindness_reaches_refuses[InsuredTest.DISABILITY]" + ], + "log": "scratch/review/round21-mutation-no_listed_prior_check.log", + "name": "no_listed_prior_check", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-no_listed_prior_check.json" + }, + { + "changes": [ + { + "after": " if _prior_start_binds(\n person, lower, upper, index, month, coverage_end_month, blind\n )\n", + "before": " if not current_unknown\n and _prior_start_binds(\n person, lower, upper, index, month, coverage_end_month, blind\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-binding_reaches_open_period.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/binding_reaches_open_period /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_an_unknown_year_leaves_a_proven_result_to_the_proof" + ], + "log": "scratch/review/round21-mutation-binding_reaches_open_period.log", + "name": "binding_reaches_open_period", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-binding_reaches_open_period.json" + }, + { + "changes": [ + { + "after": " if False:\n", + "before": " if binding and unknown:\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-unknown_year_searches.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/unknown_year_searches /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_an_unknown_year_refuses_a_prior_placement_decides" + ], + "log": "scratch/review/round21-mutation-unknown_year_searches.log", + "name": "unknown_year_searches", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-unknown_year_searches.json" + }, + { + "changes": [ + { + "after": " True\n or not (", + "before": " _prior_passes(person, filling, index, exit_month, blind=blind)\n and not (" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-keeps_every_filling.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/keeps_every_filling /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_date_only_blindness_reaches_refuses[InsuredTest.DISABILITY]" + ], + "log": "scratch/review/round21-mutation-keeps_every_filling.log", + "name": "keeps_every_filling", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-keeps_every_filling.json" + }, + { + "changes": [ + { + "after": "", + "before": " and not (\n person.prior_disability_periods[index].special_insured\n and _prior_passes(\n person,\n filling,\n index,\n exit_month,\n blind=False,\n ordinary_only=True,\n )\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-keeps_ignores_the_flag.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/keeps_ignores_the_flag /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_special_prior_stays_short_of_the_ordinary_rule" + ], + "log": "scratch/review/round21-mutation-keeps_ignores_the_flag.log", + "name": "keeps_ignores_the_flag", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-keeps_ignores_the_flag.json" + }, + { + "changes": [ + { + "after": "", + "before": " if not _keeps_priors(person, filling, binding, exit_month):\n continue\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-start_search_ignores_priors.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/start_search_ignores_priors /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_current_period_after_that_prior_refuses" + ], + "log": "scratch/review/round21-mutation-start_search_ignores_priors.log", + "name": "start_search_ignores_priors", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-start_search_ignores_priors.json" + }, + { + "changes": [ + { + "after": "", + "before": " if _keeps_priors(person, filling, binding, exit_month)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-listed_search_ignores_priors.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/listed_search_ignores_priors /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_date_only_blindness_reaches_refuses[InsuredTest.DISABILITY]" + ], + "log": "scratch/review/round21-mutation-listed_search_ignores_priors.log", + "name": "listed_search_ignores_priors", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-listed_search_ignores_priors.json" + }, + { + "changes": [ + { + "after": " year\n for index, _ in ()\n", + "before": " year\n for index, _ in binding\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-no_prior_years.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/no_prior_years /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_date_only_blindness_reaches_refuses[InsuredTest.DISABILITY]" + ], + "log": "scratch/review/round21-mutation-no_prior_years.log", + "name": "no_prior_years", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-no_prior_years.json" + }, + { + "changes": [ + { + "after": " )\n", + "before": " ) | _prior_sensitive_years(person, binding)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-start_search_skips_prior_years.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/start_search_skips_prior_years /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_reaches_a_year_the_start_cannot" + ], + "log": "scratch/review/round21-mutation-start_search_skips_prior_years.log", + "name": "start_search_skips_prior_years", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-start_search_skips_prior_years.json" + }, + { + "changes": [ + { + "after": " person, credits, start, month, exit_month, favored, ()\n ),\n start,\n", + "before": " person, credits, start, month, exit_month, favored, binding\n ),\n start,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-first_search_drops_binding.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/first_search_drops_binding /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_listed_prior_can_undercut_the_status" + ], + "log": "scratch/review/round21-mutation-first_search_drops_binding.log", + "name": "first_search_drops_binding", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-first_search_drops_binding.json" + }, + { + "changes": [ + { + "after": " for filling, completed in _fillings_keeping_start(\n person, credits, start, month, exit_month, favored, ()\n", + "before": " for filling, completed in _fillings_keeping_start(\n person, credits, start, month, exit_month, favored, binding\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-date_search_drops_binding.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/date_search_drops_binding /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_listed_prior_holds_every_ending_to_the_date" + ], + "log": "scratch/review/round21-mutation-date_search_drops_binding.log", + "name": "date_search_drops_binding", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-date_search_drops_binding.json" + }, + { + "changes": [ + { + "after": "", + "before": " *((InsuredTest.DISABILITY,) if binding else ()),\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-disability_left_out_of_search.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/disability_left_out_of_search /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_limits_what_a_status_reports" + ], + "log": "scratch/review/round21-mutation-disability_left_out_of_search.log", + "name": "disability_left_out_of_search", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-disability_left_out_of_search.json" + }, + { + "changes": [ + { + "after": " option,\n", + "before": " person if kind is InsuredTest.DISABILITY else option,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-disability_reads_the_completion.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/disability_reads_the_completion /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_an_establishment_counts_no_quarter_of_its_own_period" + ], + "log": "scratch/review/round21-mutation-disability_reads_the_completion.log", + "name": "disability_reads_the_completion", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-disability_reads_the_completion.json" + }, + { + "changes": [ + { + "after": " dated=False,\n last_insured=last_insured,\n reported=reported,\n detail=\"Annual placement decides", + "before": " dated=dated,\n last_insured=last_insured,\n reported=reported,\n detail=\"Annual placement decides" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-listed_search_skips_the_date.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/listed_search_skips_the_date /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_nonblind_filling_that_reaches_the_date_computes" + ], + "log": "scratch/review/round21-mutation-listed_search_skips_the_date.log", + "name": "listed_search_skips_the_date", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-listed_search_skips_the_date.json" + }, + { + "changes": [ + { + "after": " if not person.prior_disability_periods[index].special_insured:\n return True\n", + "before": " if not person.prior_disability_periods[index].special_insured:\n return not every\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-unflagged_refuses_every_placement.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/unflagged_refuses_every_placement /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_every_nonblind_placement_binds_nothing" + ], + "log": "scratch/review/round21-mutation-unflagged_refuses_every_placement.log", + "name": "unflagged_refuses_every_placement", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-unflagged_refuses_every_placement.json" + }, + { + "changes": [ + { + "after": " if True and not _every_placement_begins(\n person,\n lower,\n index,\n month,\n exit_month,\n blind=False,\n ordinary_only=True,\n ):\n", + "before": " if _prior_passes(\n person, upper, index, exit_month, blind=False\n ) and not _every_placement_begins(\n person,\n lower,\n index,\n month,\n exit_month,\n blind=False,\n ordinary_only=True,\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-flagged_ignores_support.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/flagged_ignores_support /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_flagged_prior_no_placement_supports_names_why[short_of_its_route]" + ], + "log": "scratch/review/round21-mutation-flagged_ignores_support.log", + "name": "flagged_ignores_support", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-flagged_ignores_support.json" + }, + { + "changes": [ + { + "after": " if _prior_passes(person, upper, index, exit_month, blind=False):\n", + "before": " if _prior_passes(\n person, upper, index, exit_month, blind=False\n ) and not _every_placement_begins(\n person,\n lower,\n index,\n month,\n exit_month,\n blind=False,\n ordinary_only=True,\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-flagged_ignores_ordinary_rule.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/flagged_ignores_ordinary_rule /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_flagged_prior_no_placement_supports_names_why[reaches_the_ordinary_rule]" + ], + "log": "scratch/review/round21-mutation-flagged_ignores_ordinary_rule.log", + "name": "flagged_ignores_ordinary_rule", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-flagged_ignores_ordinary_rule.json" + }, + { + "changes": [ + { + "after": " return True\n", + "before": " return not every or _prior_passes(\n person, upper, index, exit_month, blind=False, ordinary_only=True\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-flagged_refuses_every_placement.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/flagged_refuses_every_placement /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_an_unknown_year_leaves_a_special_prior_every_placement_carries" + ], + "log": "scratch/review/round21-mutation-flagged_refuses_every_placement.log", + "name": "flagged_refuses_every_placement", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-flagged_refuses_every_placement.json" + }, + { + "changes": [ + { + "after": " person, statutory_blindness=True, prior_disability_periods=()\n", + "before": " person, statutory_blindness=blind, prior_disability_periods=()\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-every_flagged_reads_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/every_flagged_reads_blindness /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_date_only_blindness_reaches_refuses[InsuredTest.DISABILITY]" + ], + "log": "scratch/review/round21-mutation-every_flagged_reads_blindness.log", + "name": "every_flagged_reads_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-every_flagged_reads_blindness.json" + }, + { + "changes": [ + { + "after": " person, statutory_blindness=False, prior_disability_periods=()\n", + "before": " person, statutory_blindness=blind, prior_disability_periods=()\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-every_unflagged_reads_no_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/every_unflagged_reads_no_blindness /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_one_placement_can_decide_a_nonblind_prior_alone" + ], + "log": "scratch/review/round21-mutation-every_unflagged_reads_no_blindness.log", + "name": "every_unflagged_reads_no_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-every_unflagged_reads_no_blindness.json" + }, + { + "changes": [ + { + "after": " statutory_blindness=True,\n prior_disability_periods=person.prior_disability_periods[:index],\n", + "before": " statutory_blindness=blind,\n prior_disability_periods=person.prior_disability_periods[:index],\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-route_flagged_reads_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/route_flagged_reads_blindness /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_date_only_blindness_reaches_refuses[InsuredTest.DISABILITY]" + ], + "log": "scratch/review/round21-mutation-route_flagged_reads_blindness.log", + "name": "route_flagged_reads_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-route_flagged_reads_blindness.json" + }, + { + "changes": [ + { + "after": " statutory_blindness=False,\n prior_disability_periods=person.prior_disability_periods[:index],\n", + "before": " statutory_blindness=blind,\n prior_disability_periods=person.prior_disability_periods[:index],\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-route_unflagged_reads_no_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/route_unflagged_reads_no_blindness /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_prior_only_blindness_can_begin_keeps_that_basis" + ], + "log": "scratch/review/round21-mutation-route_unflagged_reads_no_blindness.log", + "name": "route_unflagged_reads_no_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-route_unflagged_reads_no_blindness.json" + }, + { + "changes": [ + { + "after": " person,\n statutory_blindness=blind,\n prior_disability_periods=person.prior_disability_periods[:index],\n", + "before": " person, statutory_blindness=blind, prior_disability_periods=()\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-every_reads_listed_periods.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/every_reads_listed_periods /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_a_later_prior_on_an_earlier_endpoint_binds" + ], + "log": "scratch/review/round21-mutation-every_reads_listed_periods.log", + "name": "every_reads_listed_periods", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-every_reads_listed_periods.json" + }, + { + "changes": [ + { + "after": " prior_disability_periods=(),\n )\n return _witness(\n", + "before": " prior_disability_periods=person.prior_disability_periods[:index],\n )\n return _witness(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-some_drops_earlier_periods.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/some_drops_earlier_periods /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_later_prior_can_rest_on_an_earlier_one_on_either_basis" + ], + "log": "scratch/review/round21-mutation-some_drops_earlier_periods.log", + "name": "some_drops_earlier_periods", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-some_drops_earlier_periods.json" + }, + { + "changes": [ + { + "after": " every = _every_placement_begins(\n person, upper, index, month, exit_month, blind=blind\n )\n", + "before": " every = _every_placement_begins(\n person, lower, index, month, exit_month, blind=blind\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-every_on_upper_credits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/every_on_upper_credits /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_an_unknown_year_can_support_a_prior" + ], + "log": "scratch/review/round21-mutation-every_on_upper_credits.log", + "name": "every_on_upper_credits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-every_on_upper_credits.json" + }, + { + "changes": [ + { + "after": " for blind in (False, True):\n if _prior_passes(person, lower, index, exit_month, blind=blind):\n return blind\n", + "before": " for blind in (False, True):\n if _prior_passes(person, upper, index, exit_month, blind=blind):\n return blind\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-some_on_lower_credits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/some_on_lower_credits /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_an_unknown_year_can_support_a_prior" + ], + "log": "scratch/review/round21-mutation-some_on_lower_credits.log", + "name": "some_on_lower_credits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-some_on_lower_credits.json" + }, + { + "changes": [ + { + "after": " if young or subsequent:\n", + "before": " if (young or subsequent) and not ordinary_only:\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-ordinary_keeps_special_route.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/ordinary_keeps_special_route /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_flagged_prior_has_one_basis" + ], + "log": "scratch/review/round21-mutation-ordinary_keeps_special_route.log", + "name": "ordinary_keeps_special_route", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-ordinary_keeps_special_route.json" + }, + { + "changes": [ + { + "after": " person,\n person.disability_onset,\n _current_period_start_horizon(person, month),\n ) | _prior_sensitive_years(person, binding)\n", + "before": " person, person.disability_onset, start\n ) | _prior_sensitive_years(person, binding)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-fix_reverted.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/fix_reverted /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_partial_years_after_the_start_stay_open" + ], + "log": "scratch/review/round21-mutation-fix_reverted.log", + "name": "fix_reverted", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-fix_reverted.json" + }, + { + "changes": [ + { + "after": " for blind in (True,):\n if _prior_passes(person, upper, index, exit_month, blind=blind):\n return blind\n", + "before": " for blind in (False, True):\n if _prior_passes(person, upper, index, exit_month, blind=blind):\n return blind\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-basis_always_blind.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/basis_always_blind /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_date_only_blindness_reaches_refuses[InsuredTest.DISABILITY]" + ], + "log": "scratch/review/round21-mutation-basis_always_blind.log", + "name": "basis_always_blind", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-basis_always_blind.json" + }, + { + "changes": [ + { + "after": " for blind in (False,):\n if _prior_passes(person, upper, index, exit_month, blind=blind):\n return blind\n", + "before": " for blind in (False, True):\n if _prior_passes(person, upper, index, exit_month, blind=blind):\n return blind\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-basis_always_nonblind.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/basis_always_nonblind /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_prior_only_blindness_can_begin_keeps_that_basis" + ], + "log": "scratch/review/round21-mutation-basis_always_nonblind.log", + "name": "basis_always_nonblind", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-basis_always_nonblind.json" + }, + { + "changes": [ + { + "after": " every = _every_placement_begins(\n person, lower, index, month, exit_month, blind=True\n )\n", + "before": " every = _every_placement_begins(\n person, lower, index, month, exit_month, blind=blind\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-binds_ignores_basis.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/binds_ignores_basis /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_date_only_blindness_reaches_refuses[InsuredTest.DISABILITY]" + ], + "log": "scratch/review/round21-mutation-binds_ignores_basis.log", + "name": "binds_ignores_basis", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-binds_ignores_basis.json" + }, + { + "changes": [ + { + "after": " every = _every_placement_begins(\n person, lower, index, month, exit_month, blind=False\n )\n", + "before": " every = _every_placement_begins(\n person, lower, index, month, exit_month, blind=blind\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-binds_always_nonblind.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/binds_always_nonblind /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_one_placement_can_decide_a_nonblind_prior_alone" + ], + "log": "scratch/review/round21-mutation-binds_always_nonblind.log", + "name": "binds_always_nonblind", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-binds_always_nonblind.json" + }, + { + "changes": [ + { + "after": " _prior_passes(person, filling, index, exit_month, blind=True)\n and not (", + "before": " _prior_passes(person, filling, index, exit_month, blind=blind)\n and not (" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-keeps_ignores_basis.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/keeps_ignores_basis /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_date_only_blindness_reaches_refuses[InsuredTest.DISABILITY]" + ], + "log": "scratch/review/round21-mutation-keeps_ignores_basis.log", + "name": "keeps_ignores_basis", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-keeps_ignores_basis.json" + }, + { + "changes": [ + { + "after": " _prior_passes(person, filling, index, exit_month, blind=False)\n and not (", + "before": " _prior_passes(person, filling, index, exit_month, blind=blind)\n and not (" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-keeps_always_nonblind.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/keeps_always_nonblind /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_filling_keeps_a_prior_on_its_own_basis" + ], + "log": "scratch/review/round21-mutation-keeps_always_nonblind.log", + "name": "keeps_always_nonblind", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-keeps_always_nonblind.json" + }, + { + "changes": [ + { + "after": " return True\n", + "before": " _refuse(\n InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY,\n \"No annual placement supports a listed prior's first insured quarter\",\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-no_support_stands.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/no_support_stands /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_prior_no_placement_supports_refuses_for_each_test[InsuredTest.ALL]" + ], + "log": "scratch/review/round21-mutation-no_support_stands.log", + "name": "no_support_stands", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-no_support_stands.json" + }, + { + "changes": [ + { + "after": " if _prior_passes(\n person, upper, index, exit_month, blind=True\n ) and not _every_placement_begins(\n person,\n lower,\n index,\n month,\n exit_month,\n blind=False,\n ordinary_only=True,\n ):\n", + "before": " if _prior_passes(\n person, upper, index, exit_month, blind=False\n ) and not _every_placement_begins(\n person,\n lower,\n index,\n month,\n exit_month,\n blind=False,\n ordinary_only=True,\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-flagged_support_reads_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/flagged_support_reads_blindness /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_flagged_prior_no_placement_supports_names_why[short_of_its_route]" + ], + "log": "scratch/review/round21-mutation-flagged_support_reads_blindness.log", + "name": "flagged_support_reads_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-flagged_support_reads_blindness.json" + }, + { + "changes": [ + { + "after": " if _prior_passes(\n person, upper, index, exit_month, blind=False\n ) and not _every_placement_begins(\n person,\n lower,\n index,\n month,\n exit_month,\n blind=True,\n ordinary_only=True,\n ):\n", + "before": " if _prior_passes(\n person, upper, index, exit_month, blind=False\n ) and not _every_placement_begins(\n person,\n lower,\n index,\n month,\n exit_month,\n blind=False,\n ordinary_only=True,\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-flagged_ordinary_reads_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/flagged_ordinary_reads_blindness /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_flagged_prior_has_one_basis" + ], + "log": "scratch/review/round21-mutation-flagged_ordinary_reads_blindness.log", + "name": "flagged_ordinary_reads_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-flagged_ordinary_reads_blindness.json" + }, + { + "changes": [ + { + "after": " if _prior_passes(\n person, lower, index, exit_month, blind=False\n ) and not _every_placement_begins(\n person,\n lower,\n index,\n month,\n exit_month,\n blind=False,\n ordinary_only=True,\n ):\n", + "before": " if _prior_passes(\n person, upper, index, exit_month, blind=False\n ) and not _every_placement_begins(\n person,\n lower,\n index,\n month,\n exit_month,\n blind=False,\n ordinary_only=True,\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-flagged_support_on_lower_credits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/flagged_support_on_lower_credits /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_an_unknown_year_can_leave_a_flagged_prior_short_of_the_ordinary_rule" + ], + "log": "scratch/review/round21-mutation-flagged_support_on_lower_credits.log", + "name": "flagged_support_on_lower_credits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-flagged_support_on_lower_credits.json" + }, + { + "changes": [ + { + "after": " if _prior_passes(\n person, upper, index, exit_month, blind=False\n ) and not _every_placement_begins(\n person,\n upper,\n index,\n month,\n exit_month,\n blind=False,\n ordinary_only=True,\n ):\n", + "before": " if _prior_passes(\n person, upper, index, exit_month, blind=False\n ) and not _every_placement_begins(\n person,\n lower,\n index,\n month,\n exit_month,\n blind=False,\n ordinary_only=True,\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-flagged_ordinary_on_upper_credits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/flagged_ordinary_on_upper_credits /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_an_unknown_year_can_carry_a_flagged_prior_past_the_ordinary_rule" + ], + "log": "scratch/review/round21-mutation-flagged_ordinary_on_upper_credits.log", + "name": "flagged_ordinary_on_upper_credits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-flagged_ordinary_on_upper_credits.json" + }, + { + "changes": [ + { + "after": " bases = tuple(\n _prior_basis(person, lower, upper, index, month, coverage_end_month)\n for index in range(0 if current_unknown else len(person.prior_disability_periods))\n )\n", + "before": " bases = tuple(\n _prior_basis(person, lower, upper, index, month, coverage_end_month)\n for index in range(len(person.prior_disability_periods))\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-basis_skipped_on_open_period.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/basis_skipped_on_open_period /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_unknown_establishment_refuses_a_prior_no_placement_supports" + ], + "log": "scratch/review/round21-mutation-basis_skipped_on_open_period.log", + "name": "basis_skipped_on_open_period", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-basis_skipped_on_open_period.json" + }, + { + "changes": [ + { + "after": " (index, True)\n for index, blind in enumerate(bases)\n", + "before": " (index, blind)\n for index, blind in enumerate(bases)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-binding_pair_drops_basis.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/binding_pair_drops_basis /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_date_only_blindness_reaches_refuses[InsuredTest.DISABILITY]" + ], + "log": "scratch/review/round21-mutation-binding_pair_drops_basis.log", + "name": "binding_pair_drops_basis", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-binding_pair_drops_basis.json" + }, + { + "changes": [ + { + "after": " bases = tuple(\n _prior_basis(person, lower, upper, index, month, coverage_end_month)\n for index in range(len(person.prior_disability_periods) if test in (InsuredTest.ALL, InsuredTest.DISABILITY) else 0)\n )\n", + "before": " bases = tuple(\n _prior_basis(person, lower, upper, index, month, coverage_end_month)\n for index in range(len(person.prior_disability_periods))\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-basis_only_on_disability.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/basis_only_on_disability /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_prior_no_placement_supports_refuses_for_each_test[InsuredTest.FULLY]" + ], + "log": "scratch/review/round21-mutation-basis_only_on_disability.log", + "name": "basis_only_on_disability", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-basis_only_on_disability.json" + }, + { + "changes": [ + { + "after": " return not every or _prior_passes(\n person, upper, index, exit_month, blind=True, ordinary_only=True\n )\n", + "before": " return not every or _prior_passes(\n person, upper, index, exit_month, blind=False, ordinary_only=True\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-binds_flag_reads_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/binds_flag_reads_blindness /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_an_unknown_year_leaves_a_special_prior_every_placement_carries" + ], + "log": "scratch/review/round21-mutation-binds_flag_reads_blindness.log", + "name": "binds_flag_reads_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-binds_flag_reads_blindness.json" + }, + { + "changes": [ + { + "after": " return not every or _prior_passes(\n person, lower, index, exit_month, blind=False, ordinary_only=True\n )\n", + "before": " return not every or _prior_passes(\n person, upper, index, exit_month, blind=False, ordinary_only=True\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-binds_flag_on_lower_credits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/binds_flag_on_lower_credits /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_an_unknown_year_can_carry_a_flagged_prior_past_the_ordinary_rule" + ], + "log": "scratch/review/round21-mutation-binds_flag_on_lower_credits.log", + "name": "binds_flag_on_lower_credits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-binds_flag_on_lower_credits.json" + }, + { + "changes": [ + { + "after": " exit_month,\n blind=True,\n ordinary_only=True,\n", + "before": " exit_month,\n blind=False,\n ordinary_only=True,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-keeps_flag_reads_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/keeps_flag_reads_blindness /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_holds_a_qc_in_its_first_quarter" + ], + "log": "scratch/review/round21-mutation-keeps_flag_reads_blindness.log", + "name": "keeps_flag_reads_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-keeps_flag_reads_blindness.json" + }, + { + "changes": [ + { + "after": " if binding:\n favored_rows, _ = _world(", + "before": " if lo_start is not None or binding:\n favored_rows, _ = _world(" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-remove_first_start_check.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/remove_first_start_check /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[109307]" + ], + "log": "scratch/review/round21-mutation-remove_first_start_check.log", + "name": "remove_first_start_check", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-remove_first_start_check.json" + }, + { + "changes": [ + { + "after": " if False and any(\n _improves(outcome, returned, last_insured)\n for outcome in _period_outcomes(", + "before": " if any(\n _improves(outcome, returned, last_insured)\n for outcome in _period_outcomes(" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-drop_bound_refusal.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/drop_bound_refusal /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[109307]" + ], + "log": "scratch/review/round21-mutation-drop_bound_refusal.log", + "name": "drop_bound_refusal", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-drop_bound_refusal.json" + }, + { + "changes": [ + { + "after": " \"dated\": False,\n \"last_insured\": None,\n", + "before": " \"dated\": dli is not None,\n \"last_insured\": dli.upper if dli is not None else None,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-drop_dli_comparison.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/drop_dli_comparison /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_frozen_exit_after_that_prior_refuses" + ], + "log": "scratch/review/round21-mutation-drop_dli_comparison.log", + "name": "drop_dli_comparison", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-drop_dli_comparison.json" + }, + { + "changes": [ + { + "after": " return _every_placement_passes(\n person, credits, start, month, exit_month, InsuredTest.DISABILITY\n )", + "before": " return not person.prior_disability_periods and _every_placement_passes(\n person, credits, start, month, exit_month, InsuredTest.DISABILITY\n )" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-start_fixed_ignores_priors.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/start_fixed_ignores_priors /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_current_period_after_that_prior_refuses" + ], + "log": "scratch/review/round21-mutation-start_fixed_ignores_priors.log", + "name": "start_fixed_ignores_priors", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-start_fixed_ignores_priors.json" + }, + { + "changes": [ + { + "after": " horizon = _current_period_start_horizon(person, month)\n for quarter in range(_qid(start), _qid(start) + 1):\n try:\n completed, own_start = _complete_current_period(", + "before": " horizon = _current_period_start_horizon(person, month)\n for quarter in range(_qid(start), _qid(horizon) + 1):\n try:\n completed, own_start = _complete_current_period(" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round21 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round21 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND21_MUTATION=scratch/review/round21-mutation-bound_stops_at_reported_start.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp20/bound_stops_at_reported_start /tmp/tbvenv/bin/python scratch/review/run_round21_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[109307]" + ], + "log": "scratch/review/round21-mutation-bound_stops_at_reported_start.log", + "name": "bound_stops_at_reported_start", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "spec_path": "scratch/review/round21-mutation-bound_stops_at_reported_start.json" + } + ], + "round_21_runner_source": "\"\"\"Run named invented-data conformance tests with open-event auditing.\"\"\"\n\nimport hashlib\nimport json\nimport os\nfrom pathlib import Path\nimport sys\n\nCOUNTS = {\"restricted_opens\": 0, \"subprocess.Popen\": 0, \"os.system\": 0}\nBARRED = {\n \"gates.yaml\", \"adjusted_poverty.py\", \"rows.py\",\n \"ssa_trust_fund_interest_rates_2026.json\",\n \"urban2010_cola_comparison.md\", \"urban2010_fra68_comparison.md\",\n \"boomers2004_uniform_cut_comparison.md\", \"minimum_benefits_comparison.md\",\n \"m6_projection_engine.md\", \"mint8_table_user_guide.source.html\",\n \"test_anchor_provenance_erratum.py\",\n \"s0_1_power_results.json\", \"s0_1_source_audit.md\", \"s0_1_power.py\",\n \"test_s0_1_invariants.py\", \"test_s0_1_power.py\",\n \"test_s0_1_thresholds.py\",\n}\n\n\ndef audit(event, arguments):\n if event == \"open\" and isinstance(arguments[0], (str, bytes)):\n path = os.fsdecode(arguments[0])\n name = Path(path).name\n if (\n name in BARRED\n or name.startswith((\"adjusted_poverty.\", \"rows.\"))\n or \"/PolicyEngine/psid-data/\" in path\n or \"/microcosm-launch-evidence/\" in path\n or \"/dynasim-refs/\" in path\n or \"/claude-501/\" in path\n or \"/tests/s0_1/\" in path\n or \"/tests/acola_track/\" in path\n or \"/tests/cola_track_a/\" in path\n or \"/tests/fra68_track/\" in path\n ):\n COUNTS[\"restricted_opens\"] += 1\n raise RuntimeError(path)\n elif event in (\"subprocess.Popen\", \"os.system\"):\n COUNTS[event] += 1\n\n\ndef main():\n for name in (\"POPULACE_DYNAMICS_PSID_DIR\", \"POPULACE_DYNAMICS_EPUF_DIR\"):\n assert os.environ[name] == \"/nonexistent/trackb-round21\"\n assert sys.argv[1:]\n assert all(\n not argument.startswith(\"tests/\") or \".py\" in argument\n for argument in sys.argv[1:]\n )\n sys.addaudithook(audit)\n from populace_dynamics.track_b import insured_status as insured\n\n source_path = Path(insured.__file__)\n original = source_path.read_bytes()\n baseline_path = os.environ.get(\"TRACKB_ROUND16_SOURCE\")\n if baseline_path:\n baseline = Path(baseline_path).read_bytes()\n exec(compile(baseline, str(source_path), \"exec\"), insured.__dict__)\n print(\"BASELINE\", hashlib.sha256(baseline).hexdigest(), flush=True)\n spec_path = os.environ.get(\"TRACKB_ROUND21_MUTATION\")\n if spec_path:\n spec = json.loads(Path(spec_path).read_text())\n assert hashlib.sha256(original).hexdigest() == spec[\"source_sha256\"]\n source = original.decode()\n for change in spec[\"changes\"]:\n assert source.count(change[\"before\"]) == 1, change[\"before\"]\n source = source.replace(change[\"before\"], change[\"after\"], 1)\n exec(compile(source, str(source_path), \"exec\"), insured.__dict__)\n print(\"MUTATION\", spec[\"name\"], flush=True)\n import pytest\n\n try:\n return pytest.main(sys.argv[1:])\n finally:\n assert source_path.read_bytes() == original\n print(\"OPEN_AUDIT\", json.dumps(COUNTS, sort_keys=True), flush=True)\n\n\nif __name__ == \"__main__\":\n raise SystemExit(main())\n", + "round_21_note": "A cloud session ran round 21's 62 mutations at f37f7f79, the final round 21 source and test bytes, against every insured status module, with no restricted open (PR #562 comment 6594394873). The 62 are round 20's 41 re-derived at round 21's source, less unflagged_refuses_unsupported_prior, whose branch the rule no longer has, 17 of round 21's own and round 15's five mutants of the moving-start path. All 62 failed a named test.", + "round_21_test_sha256": { + "tests/test_track_b_insured_status_fix_round_21.py": "d9a93475e1e62cb475dd0ee47120a995d1b32b671cfe459a08961f24a5df0156", + "tests/test_track_b_insured_status_fix_round_20.py": "f15ef8610de8fb6138f485588ff188c6748e34ebd5cb51ee2f55735d2fa9c4cd", + "tests/test_track_b_insured_status_fix_round_19.py": "10bb8286739f187b19edac7ebe0e63115f5ba9c01f4cb573035c0d187f7b72b7", + "tests/test_track_b_insured_status_status_stress.py": "824fc5def1232fe0216ca32787a3510d25ed29b9118fccf43692cdb17c4585e6", + "tests/test_track_b_insured_status_fix_round_15.py": "018ffa1851dd971f821d5b0c19c2f7c19e64b321ec733b05111c6aeb7cdce37c", + "tests/test_track_b_insured_status.py": "6d26f71c706685e1764dea1f7151c419d100040e76b4ed2bfb57bbde03f2b00d", + "tests/test_track_b_insured_status_contract.py": "8e41a54e42a438ba191b9cd2de4ac37983cf6050512ef184f025340143a6a043", + "tests/test_track_b_insured_status_fix_round_2.py": "c1d00971949eb7d1f9ac458dfea1b5e47922fb3d0047a50a764e7400f9321835" + }, + "round_21_replay": "Write round_21_runner_source to scratch/review/run_round21_named.py. For each round_21_mutations record, write name/source_sha256/changes to its spec_path, then execute its exact command at f37f7f79. Mutations apply only in memory.", + "round_21_final_source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d" } From 7b5b126a8e946e3c91e3024de18d17cd1c5c279d Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Mon, 2 Nov 2026 22:50:17 -0500 Subject: [PATCH 37/46] Keep 404.130(c) to flagged listed priors (#562 round 22) special_insured records the 404.130(d)(1) fact of a prior "for which you were only insured under paragraph (c)", so 404.130(c) can't begin an unflagged prior alone. Round 21 let it. On the review's invented record (born 1968-02-02, a listed 1998-1999 prior before 31), f37f7f79 reported a date last insured of 2008-03-31 where 404.130(b) pins the 1998 QC in 1998Q1 and gives 2007-12-31. _witness now takes under31_route, and _prior_passes and _every_placement_begins pass it the prior's flag. An unflagged prior rests on 404.130(b), on 404.130(d) at 31 or later after a flagged prior, or on past blindness. The current period and a flagged prior keep 404.130(c). The stress oracle drops 404.130(c) for unflagged priors and lets one record mix flags, and young_basis_declaration and mixed_flag_declaration draw around the review's record and a later unflagged prior. Round 19's flagged draw stops at 1990Q4, since the interface rejects a flagged start in the quarter she attains 31. The design note records the reading of a listed prior's omitted onset (the review's low), the 70 mutations and their first pass. The tier counts add 19 unit tests. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 204 ++++++++- .../track_b/insured_status.py | 42 +- tests/README-tiers.md | 4 +- ...est_track_b_insured_status_fix_round_19.py | 5 +- ...est_track_b_insured_status_fix_round_21.py | 9 +- ...est_track_b_insured_status_fix_round_22.py | 432 ++++++++++++++++++ ...st_track_b_insured_status_status_stress.py | 173 +++++-- tests/tier_counts.json | 2 +- 8 files changed, 798 insertions(+), 73 deletions(-) create mode 100644 tests/test_track_b_insured_status_fix_round_22.py diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index 0d3bd28a6..fc57da609 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -1702,7 +1702,11 @@ and computes no payment. of the years that can move it keeps the start and attains the result. Other years stay flexible for each status. A record doesn't say which route began an unflagged prior, so that filling has to keep the prior on the strictest - route some placement meets (round 21). + route some placement meets (round 21): 404.130(b), or 404.130(d) after a + flagged prior, before past blindness, since 404.130(c) begins only a flagged + prior. A listed prior's start reads as the favorable earliest insured quarter + from an onset the record omits, so that onset adds no constraint on + placement (round 22). - `us:oasdi-insured-subsequent-special-long-period` (`_witness`, `_unknown_prior_joint_shortfall`). Act 223(c)(1)(B)(iii) asks for half the quarters after age 21 with no cap, and 404.130(d)(2) caps the test at 20 of @@ -2571,8 +2575,9 @@ a special route and not 404.130(b). A prior that every placement carries past 404.130(b) therefore holds on none. At this round the predicate read every unflagged prior as resting on past blindness, and it let a prior that holds on none pass. Round 21 replaces both: `_prior_basis` holds an unflagged prior on -404.130(b) or (c) wherever a placement meets them, and a prior no placement -supports refuses by name. +404.130(b), or 404.130(d) after a flagged prior, wherever a placement meets +them (round 22 took 404.130(c) out), and a prior no placement supports refuses +by name. Otherwise the prior picks among placements, and the logged first-start reading applies to its start: one filling of the years that can move that start must @@ -2806,7 +2811,8 @@ A period begins in a quarter its holder was insured (404.320(b)(2), 404.321(a)). `DisabilityPeriod` records no blindness, and `Person.statutory_blindness` speaks only for the present. An unflagged prior could rest on past blindness, which asks only for fully insured status -(404.130(e)), or on 404.130(b) or (c), which ask for that and more. `38a573a8` +(404.130(e)), or on a rule that asks for that and more: 404.130(b), or +404.130(d) after a flagged prior (round 22 took 404.130(c) out). `38a573a8` held every unflagged prior to fully insured status alone. That weakest test suits a possibility proof, but it let a true status or a date stand where only the blind reading reaches it. @@ -2828,7 +2834,7 @@ which only past blindness reaches. ### Each basis the record allows -404.130(b) and (c) each ask for fully insured status too, so every filling that +404.130(b) and (d) each ask for fully insured status too, so every filling that begins a prior on them also begins it on past blindness. The rule's results take the best lawful filling. A filling that begins the prior on the strictest basis and attains a result therefore proves that result on the other basis too, and a @@ -2836,12 +2842,12 @@ result no such filling attains differs between them. False results stay false on any subset of placements. `_prior_basis` picks that strictest basis, one prior at a time. It returns false -where some placement meets 404.130(b) or (c), with the earlier priors, and true -where only past blindness can begin the prior. `_prior_start_binds` then asks -whether placement decides the prior on that basis, and `_keeps_priors` tests each -filling on it, so `binding` now pairs each prior with its basis. A result none of -those fillings attains refuses by name and keeps the row's weight -(`test_a_date_only_blindness_reaches_refuses`, +where some placement meets 404.130(b), or 404.130(d) after a flagged prior, with +the earlier priors, and true where only past blindness can begin the prior. +`_prior_start_binds` then asks whether placement decides the prior on that +basis, and `_keeps_priors` tests each filling on it, so `binding` now pairs each +prior with its basis. A result none of those fillings attains refuses by name +and keeps the row's weight (`test_a_date_only_blindness_reaches_refuses`, `test_a_status_only_blindness_reaches_refuses`, `test_that_refusal_keeps_the_row`). Round 19's limits apply unchanged: an UNKNOWN year with a prior that placement decides refuses @@ -2893,12 +2899,12 @@ combination of bases allows, strictest first, and drops an empty combination. `check` and `check_no_period` now require each status and the date on every combination, the counts on the first, and at least one combination behind any computed result. `check_every_history` also reads the fillings that keep a prior -on 404.130(b) or (c). `basis_prior_declaration` redraws the record above around +on 404.130(b). `basis_prior_declaration` redraws the record above around its edge, and `two_basis_declaration` adds a prior with its own basis, in either order. `test_each_basis_matches_every_placement` compares `_prior_passes`, `_prior_basis` and `_prior_start_binds` on both bases with every placement of the drawn records, and that test also checks that each filling passing 404.130(b) or -(c) passes past blindness. +(d) passes past blindness. Refusing a prior no placement supports left 62 percent of `subsequent_declaration`'s draws refusing, so that generator now places the QCs @@ -2958,13 +2964,14 @@ These tests execute the invariants this round adds: `test_status_stress_a_current_period_after_either_basis`, `test_a_date_only_blindness_reaches_refuses`, `test_that_refusal_keeps_the_row`); -- every filling that passes 404.130(b) or (c) at a prior's start passes past +- every filling that passes 404.130(b) or (d) at a prior's start passes past blindness, and `_prior_basis` and `_prior_passes` agree with every placement on both bases (`test_each_basis_matches_every_placement`, `test_a_filling_keeps_a_prior_on_its_own_basis`); -- `_prior_basis` returns false wherever a placement meets 404.130(b) or (c), - including with an earlier prior, and true only where past blindness alone can - begin the prior (`test_each_basis_matches_every_placement`, +- `_prior_basis` returns false wherever a placement meets 404.130(b), or + 404.130(d) after a flagged prior, including with an earlier prior, and true + only where past blindness alone can begin the prior + (`test_each_basis_matches_every_placement`, `test_a_prior_only_blindness_can_begin_keeps_that_basis`, `test_a_later_prior_can_rest_on_an_earlier_one_on_either_basis`); - `_prior_start_binds` on the first prior answers true exactly where some @@ -2980,6 +2987,169 @@ These tests execute the invariants this round adds: `test_an_unknown_year_can_support_a_prior`); - a flagged prior has one basis (`test_a_flagged_prior_has_one_basis`). +## Round 22 an unflagged prior before age 31 + +Verification class: statutory conformance on invented declarations only. +This correction admits no population, behavioral, payment, or forecast claim. +An independent review of `f37f7f79` reported one medium and one low (PR #562 +comment 6592883037). + +### What the flag says + +404.130(d)(1) reaches someone "disabled again at age 31 or later after having +had a prior period of disability established which began before age 31 and for +which you were only insured under paragraph (c)". `special_insured` records +that fact, so an unflagged prior's holder wasn't only insured under 404.130(c), +and that paragraph can't begin the prior alone. A nonblind unflagged prior +rests on 404.130(b), or on 404.130(d) where it begins at 31 or later after a +flagged prior, and past blindness stays open as before. Round 21 let +404.130(c) begin an unflagged prior. Before age 31, 404.130(c) can hold a prior +on every placement while 404.130(b) holds a QC in the prior's first quarter, +and the prior then bound nothing. + +The review's record is round 21's for a woman born 1968-02-02, without the 1980 +to 1984 QCs: four QCs in each of 1989 to 1992, three in 1993, one in 1998, four +in each of 1999 to 2002 and three in 2003, with a listed prior from 1998-01-01 +through 1999-12-31, before the 1999Q1 quarter she attains 31. The 36 quarters +from 1989Q2 through 1997Q4 hold 18 QCs, half of them, so 404.130(c) holds the +prior on every placement. 404.130(b) finds 19 of 40 there and needs the 1998 QC +in 1998Q1. On that placement the date falls on 2007-12-31, and on past +blindness on 2008-03-31. `f37f7f79` reported 2008-03-31 for a January 2008 +query, DISABILITY true at a January 2008 onset, and 2008-09-30 for a 2027 query +with an exit frozen after 2003. Each now refuses by name, as do an UNKNOWN 2005 +and a current period over 2004 (`test_a_date_only_blindness_reaches_refuses`, +`test_that_refusal_keeps_the_row`, `test_with_no_onset_the_date_refuses`, +`test_a_frozen_exit_refuses`, `test_an_unknown_year_refuses`, +`test_a_current_period_after_that_prior_refuses`). A flagged prior can't meet +404.130(b), so there the 1998 QC falls later, and the record computes +2008-03-31 (`test_a_flagged_prior_there_computes`). + +### The change + +`_witness` takes `under31_route`, and `_prior_passes` and +`_every_placement_begins` pass it the prior's flag. An unflagged prior before +31 then has no special route, and one at 31 or later keeps 404.130(d) after a +flagged prior. The current period and every other caller keep 404.130(c) as +before. + +The change moves two other kinds of record. Where only 404.130(c) could begin +an unflagged prior, the record now implies past blindness +(`test_a_prior_only_paragraph_c_begins_rests_on_past_blindness`). Where +404.130(c) held such a prior to some placements, round 21 searched them and +could refuse. Past blindness now holds the prior on every placement, and with +two 1993 QCs the record computes 2008-03-31 +(`test_a_prior_paragraph_c_splits_computes_on_past_blindness`). + +After a flagged 1995 prior, the 1998Q1 prior still rests on 404.130(b), because +404.130(d) opens only at 31 +(`test_a_young_prior_after_a_flagged_one_rests_on_paragraph_b`). A prior from +1999Q2 after a flagged 1993 prior rests on 404.130(d), which counts 37 quarters +with the earlier period's four set aside, and finds 18 only with the 1999 QC by +then (`test_a_prior_past_31_after_a_flagged_one_can_rest_on_paragraph_d`). +Without the flag that prior rests on past blindness +(`test_without_the_flag_that_prior_rests_on_past_blindness`). + +The change applies the field's definition. It adds no reading of the law, so it +adds no register entry, and the one-filling entry now names the bases. The +review offered a second course, reading the flag as unknown, which would also +open 404.130(d) for later statuses. The interface declares the flag an +adjudicated fact, so the rule takes an OBSERVED false flag as false. + +### A listed prior's onset + +A listed prior records its start, not its onset. The rule reads that start as +the favorable earliest insured quarter from the onset (RS 00301.230, +404.321(a)). Had any placement insured an earlier quarter from the onset, the +period would have begun there, so every placement leaves the quarters between an +earlier onset and the start uninsured, and the onset adds no constraint on +placement. The review's probe found no wrong output under this reading. For a +woman born 1970-07-15 with a prior from 1995-04-01 through 1995-12-31, a later +status turns false only on a completion that leaves 1995Q1 uninsured, and that +completion sets aside the favorable placement that insures 1995Q1. + +### Oracle and generators + +The stress oracle's `prior_holds` now holds an unflagged prior to 404.130(b), +or 404.130(d) after a flagged prior, and `prior_can_begin` holds an added prior +to 404.130(b) on its nonblind basis. `disability` takes `paragraph_c`, and +`flags` reads each prior's flag, so a record can mix flagged and unflagged +priors. `two_basis_declaration` now draws a 1984Q1 prior that only past +blindness begins, though 404.130(c) alone would, a 1985Q1 prior on 404.130(b), +or round 21's 1986Q2 prior. `young_basis_declaration` redraws the review's +record around its edges and flags a quarter of the draws, and +`mixed_flag_declaration` adds an unflagged prior after +`subsequent_declaration`'s flagged one. Round 22's +`test_each_basis_matches_every_placement` compares `_keeps_priors`, +`_prior_basis` and `_prior_start_binds` with every placement of those draws, and +`test_a_later_prior_after_a_flagged_one_matches_every_placement` does the same +for a later prior on either side of 31. + +Over seeds 0 to 59, `young_basis_declaration` computes 45 draws and refuses 15 +by name with no current period. With a current period over 2004 it computes 42, +refuses 17 and draws one record the interface rejects. At `f37f7f79` the oracle +fails two of the 60 draws on both checks. Over seeds 0 to +39, `mixed_flag_declaration` puts 32 later priors at 31 or later and 8 before, +and no draw separates `f37f7f79` from this round, so that generator checks +404.130(d) for an unflagged prior end to end, and the round's own tests carry +the case before 31. + +Round 19's `test_placement_binds_a_prior_only_when_it_splits_them` let a +flagged prior begin in 1991Q1, the quarter she attains 31, which the interface +rejects, and CI drew that case at `f37f7f79`. The test now draws flagged starts +through 1990Q4, and its oracle holds an unflagged prior to 404.130(b). + +The list of mutations (`scratch/review/round22_mutate.py`) takes round 21's 62 +at this round's source and re-derives `ordinary_keeps_special_route`, which +drops `not ordinary_only`, against the new condition. It adds eight of this +round's own, for 70. `unflagged_reads_paragraph_c` in `_witness`, and +`route_reads_paragraph_c` and `every_reads_paragraph_c` in `_prior_passes` and +`_every_placement_begins`, give an unflagged prior 404.130(c) again. +`young_takes_subsequent_route` gives an unflagged prior before 31 the special +route once a flagged prior precedes it, and `unflagged_drops_paragraph_d` takes +404.130(d) from an unflagged prior. `route_drops_flagged_paragraph_c` and +`every_drops_flagged_paragraph_c` take 404.130(c) from a flagged prior, and +`current_drops_paragraph_c` takes it from the current period. + +A first pass of all 70 through rounds 19 to 22 ran with no restricted open, and +66 failed a named test, 34 of them first in round 22's module. Round 22's tests +kill six of the eight new mutants first. Round 21's +`test_an_unknown_year_can_carry_a_flagged_prior_past_the_ordinary_rule` kills +`every_drops_flagged_paragraph_c`, and round 19's +`test_a_prior_holds_a_qc_in_its_first_quarter` kills +`current_drops_paragraph_c`. As at round 21, round 15's module kills the three +moving-start mutants that pass rounds 19 to 22: `remove_first_start_check` +first on `test_no_filling_carries_the_start_and_the_status_together`, and +`drop_bound_refusal` and `bound_stops_at_reported_start` on +`test_the_date_last_insured_alone_can_refuse_a_moving_start`. Round 2's +`test_unknown_period_status_and_dli_bounds_contain_concrete_fillings` kills +`date_tested_at_query`. + +Against `f37f7f79`, 13 of round 22's 17 tests fail, as do +`test_status_stress_a_young_prior_on_either_basis` and round 21's +`test_each_basis_matches_every_placement`. The four that pass check the +arithmetic, the flagged record, 404.130(d) after a flagged prior and the record +at 31 without a flag, which the change leaves alone. + +These tests execute the invariants this round adds: + +- an unflagged prior's nonblind basis is 404.130(b), or 404.130(d) at 31 or + later after a flagged prior, never 404.130(c) alone, and `_keeps_priors`, + `_prior_basis` and `_prior_start_binds` agree with every placement on each + basis (`test_each_basis_matches_every_placement`, + `test_a_later_prior_after_a_flagged_one_matches_every_placement`, + `test_a_young_prior_after_a_flagged_one_rests_on_paragraph_b`, + `test_a_prior_past_31_after_a_flagged_one_can_rest_on_paragraph_d`, + `test_only_paragraph_b_binds_the_prior`); +- a flagged prior keeps 404.130(c) (`test_a_flagged_prior_there_computes`, + `test_a_prior_only_paragraph_c_begins_rests_on_past_blindness`); +- a computed status or date on an unflagged prior before 31 holds on each basis + some placement allows, and otherwise the row refuses by name and keeps its + weight (`check`, `check_no_period`, + `test_status_stress_a_young_prior_on_either_basis`, + `test_a_date_only_blindness_reaches_refuses`, + `test_that_refusal_keeps_the_row`); +- the current period keeps 404.130(c) (`test_status_stress_under_31`). + ## Not in scope No real data, population evaluation, baseline claiming hazard, behavioral diff --git a/src/populace_dynamics/track_b/insured_status.py b/src/populace_dynamics/track_b/insured_status.py index 6486e163f..8eee58a3b 100644 --- a/src/populace_dynamics/track_b/insured_status.py +++ b/src/populace_dynamics/track_b/insured_status.py @@ -1237,6 +1237,7 @@ def _witness( ignore_fully_insured=False, use_periods_only=None, ordinary_only=False, + under31_route=True, ): end = _qid(at) best = None @@ -1316,7 +1317,12 @@ def _witness( subsequent = any( p.special_insured for p in person.prior_disability_periods ) - if (young or subsequent) and not ordinary_only: + # A flag records a prior "for which you were only insured + # under paragraph (c)" (404.130(d)(1)), so 404.130(c) can't + # begin an unflagged prior alone. + if not ordinary_only and ( + young and under31_route or subsequent and not young + ): first = max( 1937 * 4, _qid(_attain(person.birth_date, 21)) + 1 ) @@ -1722,7 +1728,9 @@ def _prior_passes(person, credits, index, exit_month, *, blind, **options): """Whether a route insures a listed prior's start, with earlier priors. ``blind`` reads the holder as blind then, which asks only for fully - insured status (404.130(e)). + insured status (404.130(e)). Only a flagged prior can begin on 404.130(c) + alone, and an unflagged one rests on 404.130(b), or on 404.130(d) after a + flagged prior. """ period = person.prior_disability_periods[index] earlier = replace( @@ -1736,6 +1744,7 @@ def _prior_passes(person, credits, index, exit_month, *, blind, **options): period.start, exit_month, InsuredTest.DISABILITY, + under31_route=period.special_insured, **options, )[0] @@ -1772,15 +1781,17 @@ def _every_placement_begins( earlier priors, so a later prior resting on one fails here, and the search that follows then keeps the fillings it holds on. """ + period = person.prior_disability_periods[index] return _every_placement_passes( replace( person, statutory_blindness=blind, prior_disability_periods=() ), lower, - person.prior_disability_periods[index].start, + period.start, month, exit_month, InsuredTest.DISABILITY, + under31_route=period.special_insured, **options, ) @@ -1789,18 +1800,19 @@ def _prior_basis(person, lower, upper, index, month, exit_month): """Whether past blindness alone can support a listed prior's start. A period begins in a quarter its holder was insured (404.320(b)(2), - 404.321(a)). The record doesn't say whether an unflagged prior rested on - past blindness, which asks only for fully insured status (404.130(e)), or - on 404.130(b) or (c), which ask for that and more. A result has to stand - on each basis some placement allows. Every placement 404.130(b) or (c) - allows also passes 404.130(e), so a filling that keeps the prior on them - speaks for both, and they hold the prior wherever a placement meets them. - A flagged prior's holder "were only insured under paragraph (c)" - (404.130(d)(1)), so no placement supports that prior if none passes a - route or all of them pass 404.130(b). A prior no placement supports rests - on credits or facts this record omits, and those could move other results, - so the rule refuses it by name. Upper credits bound every completion of an - UNKNOWN year. + 404.321(a)). A flag records a prior "for which you were only insured under + paragraph (c)" (404.130(d)(1)), so no placement supports a flagged prior + if none passes a route or all of them pass 404.130(b), and 404.130(c) + can't begin an unflagged prior alone. The record doesn't say whether an + unflagged prior rested on past blindness, which asks only for fully + insured status (404.130(e)), or on 404.130(b), or (d) after a flagged + prior, which ask for that and more. A result has to stand on each basis some placement + allows. Every placement 404.130(b) or (d) allows also passes 404.130(e), + so a filling that keeps the prior on them speaks for both, and they hold + the prior wherever a placement meets them. A prior no placement supports + rests on credits or facts this record omits, and those could move other + results, so the rule refuses it by name. Upper credits bound every + completion of an UNKNOWN year. """ if person.prior_disability_periods[index].special_insured: if _prior_passes( diff --git a/tests/README-tiers.md b/tests/README-tiers.md index d5eb489b7..5a152b6eb 100644 --- a/tests/README-tiers.md +++ b/tests/README-tiers.md @@ -39,9 +39,9 @@ pytest --collect-only -q -m oracle_policyengine | tail -1 | Tier | Tests at HEAD | |---|---:| -| `unit` | 25,426 | +| `unit` | 25,445 | | `artifact` | 4,271 | | `integration_psid` | 1,471 | | `reproduction_legacy` | 520 | | `oracle_policyengine` | 337 | -| **Total** | **32,025** | +| **Total** | **32,044** | diff --git a/tests/test_track_b_insured_status_fix_round_19.py b/tests/test_track_b_insured_status_fix_round_19.py index c2205b874..f81020708 100644 --- a/tests/test_track_b_insured_status_fix_round_19.py +++ b/tests/test_track_b_insured_status_fix_round_19.py @@ -847,7 +847,7 @@ def test_the_worst_filling_matches_every_placement( def _lawful_prior(birth, credits, begins, special, blind=True): at = quarter(begins) if not special: - return disability(birth, credits, at, (), blind) + return disability(birth, credits, at, (), blind, paragraph_c=False) return ( disability(birth, credits, at, (), False) and recent(usable(credits, at, ()), at, (), 40) < 20 @@ -866,7 +866,8 @@ def test_placement_binds_a_prior_only_when_it_splits_them( ): birth = date(1960, 2, 2) begins = date(begins_year, 3 * begins_quarter + 1, 1) - assume(not special or begins < date(1991, 2, 2)) + # A flag needs a start before the quarter she attains 31, 1991Q1. + assume(not special or begins < date(1991, 1, 1)) prior = i.DisabilityPeriod( begins, date(begins_year, 12, 31), special_insured=special ) diff --git a/tests/test_track_b_insured_status_fix_round_21.py b/tests/test_track_b_insured_status_fix_round_21.py index 8deb4e37b..016aee53a 100644 --- a/tests/test_track_b_insured_status_fix_round_21.py +++ b/tests/test_track_b_insured_status_fix_round_21.py @@ -7,10 +7,11 @@ A DisabilityPeriod records no blindness, and Person.statutory_blindness speaks only for the present, so a record doesn't say whether an unflagged prior rested on past blindness, which asks only for fully insured status (404.130(e)), or on -404.130(b) or (c), which ask for that and more. A computed result has to stand -on each basis some placement allows. +404.130(b), or (d) after a flagged prior, which ask for that and more (round 22 +keeps 404.130(c) to flagged priors). A computed result has to stand on each +basis some placement allows. -Every placement 404.130(b) or (c) allows also passes 404.130(e), so a filling +Every placement 404.130(b) or (d) allows also passes 404.130(e), so a filling that keeps the prior on them speaks for both. A result none attains refuses by name. A prior no placement supports on any basis rests on credits or facts the record omits, and those could move other results, so it refuses by name too. @@ -319,7 +320,7 @@ def test_each_basis_matches_every_placement(seed, declare): ) is expected ), (case, sorted(filling), index, blind) - # 404.130(b) and (c) ask for fully insured status too. + # 404.130(b) and (d) ask for fully insured status too. assert all( passes or not strict for strict, passes in zip(held[False], held[True], strict=True) diff --git a/tests/test_track_b_insured_status_fix_round_22.py b/tests/test_track_b_insured_status_fix_round_22.py new file mode 100644 index 000000000..1ff5ae27b --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_22.py @@ -0,0 +1,432 @@ +"""Round 22: an unflagged prior before age 31 can't rest on 404.130(c). + +Verification class: statutory conformance on invented declarations; no +population, behavioral or forecast claim. + +404.130(d)(1) reaches someone "disabled again at age 31 or later after having +had a prior period of disability established which began before age 31 and +for which you were only insured under paragraph (c)". DisabilityPeriod records +that fact as ``special_insured``, so an unflagged prior's holder wasn't only +insured under 404.130(c), and 404.130(c) can't begin that prior alone. It rests +on 404.130(b), on 404.130(d) after a flagged prior, or on past blindness +(404.130(e)), and a computed result has to stand on each basis some placement +allows. + +Before this round 404.130(c) could begin an unflagged prior. It can hold a +prior on every placement while 404.130(b) holds a QC in the prior's first +quarter, so the prior bound nothing, and a date only past blindness reaches +came back computed. +""" + +from datetime import date + +import pytest +from hypothesis import assume, given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as i +from tests.test_track_b_insured_status_fix_round_17 import ( + ASSIGNMENT, + LONG, + OBSERVED, + _history, + _refused_with, + _result, +) +from tests.test_track_b_insured_status_fix_round_19 import ( + _credits, + _unknown_year, +) +from tests.test_track_b_insured_status_fix_round_20 import ( + LISTED_PRIOR, + _filling, + _refusal, +) +from tests.test_track_b_insured_status_status_stress import ( + LAST_40, + YOUNG_PRIOR, + check_no_period, + disability, + flags, + last_insured, + mixed_flag_declaration, + placements, + prior_holds, + quarter, + two_basis_declaration, + young_basis_declaration, +) + +ALL = i.InsuredTest.ALL +DISABILITY = i.InsuredTest.DISABILITY +BIRTH = YOUNG_PRIOR["birth"] +ANNUAL = YOUNG_PRIOR["annual"] +MONTH = YOUNG_PRIOR["month"] +PRIOR = i.DisabilityPeriod(*YOUNG_PRIOR["prior"][0]) +FLAGGED = i.DisabilityPeriod(PRIOR.start, PRIOR.end, special_insured=True) +# Without the 1998 QC, 404.130(c) finds 18 of 36 at 1998Q1 and 404.130(b) 19 of +# 40, on the one placement. +NO_1998 = {year: n for year, n in ANNUAL.items() if year != 1998} +# Two 1993 QCs leave 404.130(c) the 1998 QC to hold in 1998Q1, and 404.130(b) +# 19 of 40 at most. +TWO_1993 = {**ANNUAL, 1993: 2} +# 18 of the 24 quarters 1989Q2 to 1995Q1 pass 404.130(c), and 19 of 40 fall +# short of 404.130(b), so a flag fits this prior. +EARLY_FLAG = i.DisabilityPeriod( + date(1995, 1, 1), date(1995, 12, 31), special_insured=True +) +# A flagged 1993 prior finds 9 of the 16 quarters 1989Q2 to 1993Q1 and 10 of +# 40. At 1999Q2, past the 1999Q1 quarter she attains 31, 404.130(d) counts 37 +# quarters with that prior's four set aside, and finds 18 only with the 1999 QC +# by then. 404.130(b) finds 19 of 40 at most. +D_FLAG = i.DisabilityPeriod( + date(1993, 1, 1), date(1993, 12, 31), special_insured=True +) +D_PRIOR = i.DisabilityPeriod(date(1999, 4, 1), date(1999, 12, 31)) +D_ANNUAL = {1989: 4, 1990: 4, 1991: 2, 1994: 4, 1995: 4, 1999: 1} + + +def _young(*priors, **changes): + values = dict( + sex=i.Sex.FEMALE, + disability_onset=None, + current_disability_period_established=False, + current_disability_period_provenance=OBSERVED, + prior_disability_periods=priors or (PRIOR,), + prior_disability_periods_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + values.update(changes) + return i.Person(BIRTH, **values) + + +def _years(annual=ANNUAL, last=MONTH.year): + return _history(BIRTH.year, last, annual) + + +def _basis(person, annual, index=0, month=MONTH): + credits = _credits(annual) + return i._prior_basis(person, credits, credits, index, month, None) + + +def _case(*priors, annual=ANNUAL): + return { + **YOUNG_PRIOR, + "annual": annual, + "prior": tuple((p.start, p.end) for p in priors), + "flags": tuple(p.special_insured for p in priors), + } + + +# The reviewed record. + + +def test_paragraph_c_holds_every_placement_and_paragraph_b_one_quarter(): + # Plain arithmetic: 404.130(c) finds 18 of the 36 quarters from 1989Q2 on + # every placement. 404.130(b) finds 19 of 40 there, so it holds the 1998 QC + # in 1998Q1. The 40 quarters through 2008Q1 reach 20 only with that QC + # later, and 2007Q4 counts it. + every = tuple(placements(ANNUAL)) + at = quarter(PRIOR.start) + either = [c for c in every if disability(BIRTH, c, at, (), False)] + nonblind = [c for c in every if prior_holds(YOUNG_PRIOR, c, 0, False)] + blind = [c for c in every if prior_holds(YOUNG_PRIOR, c, 0, True)] + assert len(either) == len(blind) == len(every) + assert nonblind + assert all(at in credits for credits in nonblind) + + def best(fillings): + return max( + last_insured( + BIRTH, credits, quarter(MONTH), periods, False, False, LAST_40 + ) + for credits in fillings + for periods in (YOUNG_PRIOR["prior"], ()) + ) + + assert best(either) == best(blind) == quarter(date(2008, 1, 1)) + assert best(nonblind) == quarter(date(2007, 10, 1)) + + +@pytest.mark.parametrize("test", (DISABILITY, ALL)) +def test_a_date_only_blindness_reaches_refuses(test): + refused = _refusal( + _young(disability_onset=MONTH), _years(), MONTH, test=test + ) + assert refused.reason is ASSIGNMENT + assert refused.detail == LISTED_PRIOR + + +def test_that_refusal_keeps_the_row(): + _refused_with( + ASSIGNMENT, + _young(disability_onset=MONTH), + _years(), + MONTH, + test=DISABILITY, + ) + + +def test_with_no_onset_the_date_refuses(): + assert _refusal(_young(), _years(), MONTH).detail == LISTED_PRIOR + assert check_no_period(YOUNG_PRIOR) == "refused" + + +def test_a_frozen_exit_refuses(): + # The exit keeps the QCs through 2003, and the date past it still turns + # on where the prior puts the 1998 QC. + refused = _refusal( + _young(), + _years(last=2003), + date(2027, 1, 1), + test=DISABILITY, + coverage_end_month=date(2003, 12, 1), + ) + assert refused.detail == LISTED_PRIOR + + +def test_an_unknown_year_refuses(): + refused = _refusal( + _young(), _unknown_year(_years(), 2005), MONTH, test=DISABILITY + ) + assert refused.detail == LISTED_PRIOR + + +def test_a_current_period_after_that_prior_refuses(): + refused = _refusal( + _young( + disability_onset=date(2004, 1, 1), + current_disability_period_established=True, + current_disability_period_end=date(2004, 12, 31), + current_disability_period_end_provenance=OBSERVED, + ), + _years(), + MONTH, + ) + assert refused.reason is ASSIGNMENT + assert refused.detail.startswith("First insured start depends") + + +def test_a_flagged_prior_there_computes(): + # A flag rules 404.130(b) out at 1998Q1, so the 1998 QC falls later, and + # the 40 quarters through 2008Q1 hold 20. + result = _result( + _young(FLAGGED, disability_onset=MONTH), + _years(), + MONTH, + test=DISABILITY, + ) + assert result.disability.insured + assert result.dli.upper == date(2008, 3, 31) + assert check_no_period({**YOUNG_PRIOR, "special": True}) == "computed" + + +# Where 404.130(c) alone could begin the prior. + + +def test_a_prior_only_paragraph_c_begins_rests_on_past_blindness(): + assert _basis(_young(), NO_1998) is True + assert _basis(_young(FLAGGED), NO_1998) is False + + +def test_a_prior_paragraph_c_splits_computes_on_past_blindness(): + # Past blindness holds the prior on every placement, so the date reaches + # 2008Q1. Read on 404.130(c), the prior held the 1998 QC in 1998Q1, and + # the rule refused. + assert _basis(_young(), TWO_1993) is True + result = _result(_young(), _years(TWO_1993), MONTH, test=DISABILITY) + assert result.dli.upper == date(2008, 3, 31) + assert check_no_period({**YOUNG_PRIOR, "annual": TWO_1993}) == "computed" + + +def test_only_paragraph_b_binds_the_prior(): + person = _young() + credits = _credits(ANNUAL) + assert _basis(person, ANNUAL) is False + assert i._prior_start_binds( + person, credits, credits, 0, MONTH, None, False + ) + assert not i._prior_start_binds( + person, credits, credits, 0, MONTH, None, True + ) + first, later = ( + _filling( + ANNUAL, + next( + credits + for credits in placements(ANNUAL) + if (quarter(PRIOR.start) in credits) is wanted + ), + ) + for wanted in (True, False) + ) + assert i._keeps_priors(person, first, ((0, False),), None) + assert not i._keeps_priors(person, later, ((0, False),), None) + assert i._keeps_priors(person, later, ((0, True),), None) + + +# After a flagged prior. + + +def test_a_young_prior_after_a_flagged_one_rests_on_paragraph_b(): + # 404.130(d) opens only at 31, so the flagged 1995 prior leaves the 1998Q1 + # prior where it was: on 404.130(b), with the 1998 QC in 1998Q1. + person = _young(EARLY_FLAG, PRIOR) + case = _case(EARLY_FLAG, PRIOR) + assert _basis(person, ANNUAL, 0) is False + for credits in placements(ANNUAL): + expected = quarter(PRIOR.start) in credits + filling = _filling(ANNUAL, credits) + assert prior_holds(case, credits, 1, False) is expected + assert i._prior_passes(person, filling, 1, None, blind=False) is ( + expected + ) + assert _basis(person, ANNUAL, 1) is False + credits = _credits(ANNUAL) + assert i._prior_start_binds( + person, credits, credits, 1, MONTH, None, False + ) + + +def test_a_prior_past_31_after_a_flagged_one_can_rest_on_paragraph_d(): + person = _young(D_FLAG, D_PRIOR) + case = _case(D_FLAG, D_PRIOR, annual=D_ANNUAL) + assert _basis(person, D_ANNUAL, 0) is False + held = set() + for credits in placements(D_ANNUAL): + expected = bool(credits & {quarter(date(1999, m, 1)) for m in (1, 4)}) + filling = _filling(D_ANNUAL, credits) + assert prior_holds(case, credits, 1, False) is expected + assert i._prior_passes(person, filling, 1, None, blind=False) is ( + expected + ) + assert not i._prior_passes( + person, filling, 1, None, blind=False, ordinary_only=True + ) + held.add(expected) + assert held == {False, True} + assert _basis(person, D_ANNUAL, 1) is False + credits = _credits(D_ANNUAL) + assert i._prior_start_binds( + person, credits, credits, 1, MONTH, None, False + ) + + +def test_without_the_flag_that_prior_rests_on_past_blindness(): + plain = i.DisabilityPeriod(D_FLAG.start, D_FLAG.end) + assert _basis(_young(plain, D_PRIOR), D_ANNUAL, 1) is True + + +# Each basis against every placement. + + +def _case_person(case): + return i.Person( + case["birth"], + sex=i.Sex.FEMALE, + prior_disability_periods=tuple( + i.DisabilityPeriod(a, b, special_insured=flag) + for (a, b), flag in zip(case["prior"], flags(case), strict=True) + ), + prior_disability_periods_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + + +def _check_unflagged_bases(case): + """Each unflagged prior's basis, against every placement.""" + annual = case["annual"] + every = tuple(placements(annual)) + person = _case_person(case) + credits = _credits(annual) + for index, flag in enumerate(flags(case)): + if flag: + continue + held = { + blind: [prior_holds(case, c, index, blind) for c in every] + for blind in (False, True) + } + for blind, expected in held.items(): + for filling, holds in zip(every, expected, strict=True): + try: + passes = i._keeps_priors( + person, + _filling(annual, filling), + ((index, blind),), + None, + ) + except i.InsuredConfigurationUnsupported as error: + # Past 40 counted quarters the readings of 404.130(d) + # part ways, and the rule refuses by name. + assert error.reason is LONG + continue + assert passes is holds, (case, sorted(filling), index, blind) + if not any(held[True]): + continue + try: + basis = i._prior_basis( + person, credits, credits, index, case["month"], None + ) + except i.InsuredConfigurationUnsupported as error: + assert error.reason is LONG + continue + assert basis is (not any(held[False])), (case, index) + binds = i._prior_start_binds( + person, credits, credits, index, case["month"], None, basis + ) + assert binds or all(held[basis]), (case, index) + if index == 0: + assert binds is not all(held[basis]), (case, index) + + +@settings(max_examples=60, deadline=None, derandomize=True) +@given( + seed=st.integers(0, 2**32 - 1), + declare=st.sampled_from( + ( + young_basis_declaration, + mixed_flag_declaration, + two_basis_declaration, + ) + ), +) +def test_each_basis_matches_every_placement(seed, declare): + case = declare(seed) + assume(sum(1 for _ in placements(case["annual"])) <= 96) + _check_unflagged_bases(case) + + +YEARS = st.integers(1988, 2000) +ANNUALS = st.builds( + lambda full, partial: {**dict.fromkeys(full, 4), **partial}, + st.sets(YEARS, min_size=2, max_size=8), + st.dictionaries(YEARS, st.integers(1, 3), max_size=2), +) + + +@settings(max_examples=150, deadline=None, derandomize=True) +@given( + annual=ANNUALS, + flagged_at=st.integers(1990 * 4, 1998 * 4 + 3), + gap=st.integers(1, 12), +) +def test_a_later_prior_after_a_flagged_one_matches_every_placement( + annual, flagged_at, gap +): + # The flagged prior begins before the 1999Q1 quarter she attains 31 and + # runs through its year. The later prior then falls on either side of it. + begins = date(flagged_at // 4, 3 * (flagged_at % 4) + 1, 1) + later_at = (flagged_at // 4 + 1) * 4 + gap - 1 + later = date(later_at // 4, 3 * (later_at % 4) + 1, 1) + case = { + **YOUNG_PRIOR, + "annual": annual, + "prior": ( + (begins, date(begins.year, 12, 31)), + (later, date(later.year, 12, 31)), + ), + "flags": (True, False), + } + _check_unflagged_bases(case) diff --git a/tests/test_track_b_insured_status_status_stress.py b/tests/test_track_b_insured_status_status_stress.py index bdae0e1da..18ea48e2f 100644 --- a/tests/test_track_b_insured_status_status_stress.py +++ b/tests/test_track_b_insured_status_status_stress.py @@ -11,12 +11,15 @@ blindness in a quarter of cases all vary by seed. A second generator adds a DIB entitlement month, which ends a CURRENTLY window before the onset. A third draws ages 22-30 at onset, where 404.130(c) applies. A fourth declares a -special-insured prior after age 31, where 404.130(d) applies. A declared prior -limits the fillings only through its own start (``prior_holds``), and a record -doesn't say whether an unflagged prior rested on past blindness, so a computed -result has to stand on each basis the record allows (``basis_worlds``). No -flags, raw earnings or death are claimed, and UNKNOWN facts appear only in -``check_unknown_ending`` and ``check_every_history``. +special-insured prior before age 31 and an onset after it, where 404.130(d) +applies, and a fifth adds an unflagged prior between them. A declared prior +limits the fillings only through its own start (``prior_holds``). An unflagged +prior's holder wasn't "only insured under paragraph (c)" (404.130(d)(1)), so +404.130(c) can't begin it alone, and a record doesn't say whether it rested on +past blindness, so a computed result has to stand on each basis the record +allows (``basis_worlds``). No flags, raw earnings or death are claimed, and +UNKNOWN facts appear only in ``check_unknown_ending`` and +``check_every_history``. Every annual placement and both all-prior treatments are enumerated. A lawful filling has its own first insured start (404.321(a)), and that start supplies @@ -135,14 +138,29 @@ def under_31(birth, use, at, periods, special=False, reading=LAST_40): def disability( - birth, credits, at, periods, blind, special=False, reading=LAST_40 + birth, + credits, + at, + periods, + blind, + special=False, + reading=LAST_40, + *, + paragraph_c=True, ): + """404.130(b) to (e) at one quarter of one filling. + + ``paragraph_c`` false leaves out 404.130(c), which can't begin an + unflagged prior alone (404.130(d)(1)). + """ use = usable(credits, at, periods) fully = len(use) >= requirement(birth, at // 4, periods) + young = at < quarter(date(birth.year + 31, birth.month, birth.day)) return fully and ( blind or recent(use, at, periods, 40) >= 20 - or under_31(birth, use, at, periods, special, reading) + or (paragraph_c or not young) + and under_31(birth, use, at, periods, special, reading) ) @@ -160,6 +178,13 @@ def last_insured(birth, credits, at, periods, blind, special, reading): ) +def flags(case): + """Each declared prior's special_insured flag.""" + return case.get( + "flags", (case.get("special", False),) * len(case["prior"]) + ) + + def placements(annual): options = [ tuple(combinations(range(year * 4, year * 4 + 4), count)) @@ -184,7 +209,7 @@ def lawful_fillings(case, reading=LAST_40, *, keep=None, dated=True): case["month"], ) blind, prior, annual = case["blind"], case["prior"], case["annual"] - special = case.get("special", False) + special = any(flags(case)) at = quarter(month) events = [ event for event in (case.get("entitlement"),) if event is not None @@ -316,10 +341,8 @@ def public(case, **options): rule.EarningsProvenance.UNKNOWN if through is None else observed ), prior_disability_periods=tuple( - rule.DisabilityPeriod( - a, b, special_insured=case.get("special", False) - ) - for a, b in case["prior"] + rule.DisabilityPeriod(a, b, special_insured=flag) + for (a, b), flag in zip(case["prior"], flags(case), strict=True) ), prior_disability_periods_provenance=( rule.EarningsProvenance.UNKNOWN if unknown_prior else observed @@ -529,10 +552,19 @@ def prior_can_begin(case, credits, periods, blind=True): """404.130(a), (e): even a blind prior begins fully insured. Each prior counts the periods before it or disregards them (404.130(f)). + These priors carry no flag, so a nonblind one rests on 404.130(b) + (404.130(d)(1)). """ return all( any( - disability(case["birth"], credits, quarter(begins), used, blind) + disability( + case["birth"], + credits, + quarter(begins), + used, + blind, + paragraph_c=False, + ) for used in (periods[:index], ()) ) for index, (begins, _) in enumerate(periods) @@ -542,14 +574,24 @@ def prior_can_begin(case, credits, periods, blind=True): def prior_holds(case, credits, index, blind=True): """One declared prior's own start on one filling, on one basis. - An unflagged prior rests on past blindness, which asks only for full - insurance (404.130(e)), or on 404.130(b) or (c). A flagged prior's holder - "were only insured under paragraph (c)" (404.130(d)(1)). + A flag records a prior "for which you were only insured under paragraph + (c)" (404.130(d)(1)). An unflagged prior rests on past blindness, which + asks only for full insurance (404.130(e)), on 404.130(b), or on + 404.130(d) after a flagged prior. """ at = quarter(case["prior"][index][0]) - if not case.get("special"): + marks = flags(case) + if not marks[index]: return any( - disability(case["birth"], credits, at, used, blind) + disability( + case["birth"], + credits, + at, + used, + blind, + any(marks[:index]), + paragraph_c=False, + ) for used in (case["prior"][:index], ()) ) return ( @@ -565,11 +607,13 @@ def basis_worlds(case, fillings): rest on either basis. The first world is the strictest with a filling, and a prior no filling supports on any basis leaves no world. """ - count = len(case["prior"]) - bases = ( - ((False,) * count,) - if case.get("special") - else tuple(product((False, True), repeat=count)) + marks = flags(case) + bases = tuple( + basis + for basis in product((False, True), repeat=len(marks)) + if not any( + blind and flag for blind, flag in zip(basis, marks, strict=True) + ) ) worlds = ( [ @@ -588,7 +632,7 @@ def basis_worlds(case, fillings): def check(case): worlds = tuple( lawful_fillings(case, reading) - for reading in (READINGS if case.get("special") else READINGS[:1]) + for reading in (READINGS if any(flags(case)) else READINGS[:1]) ) try: result = public(case) @@ -630,7 +674,7 @@ def no_period_fillings(case, reading=LAST_40): The positions match ``lawful_fillings``, and no filling has a start. """ birth, month, blind = case["birth"], case["month"], case["blind"] - special = case.get("special", False) + special = any(flags(case)) at = quarter(month) found = [] for credits in placements(case["annual"]): @@ -690,7 +734,7 @@ def check_no_period(case): result = public({**case, "no_period": True}) except rule.InsuredConfigurationUnsupported: return "refused" - for reading in READINGS if case.get("special") else READINGS[:1]: + for reading in READINGS if any(flags(case)) else READINGS[:1]: bases = basis_worlds(case, no_period_fillings(case, reading)) assert bases, (case, "computed a prior no filling supports", result) for fillings in bases: @@ -1020,6 +1064,13 @@ def check_every_history( 2003: 3, }, } +# The same record for a woman born in 1968. The 1998Q1 prior then falls before +# age 31, and 404.130(c) holds it on every placement with 18 of its 36 quarters. +YOUNG_PRIOR = { + **BASIS_PRIOR, + "birth": date(1968, 2, 2), + "annual": {y: n for y, n in BASIS_PRIOR["annual"].items() if y > 1988}, +} # 18 of 37 elapsed quarters pass the route at 1990Q2, and 20 of 40 pass the # ordinary rule. SPECIAL_PRIOR = { @@ -1110,19 +1161,60 @@ def basis_prior_declaration(seed): def two_basis_declaration(seed): """The same record after a prior with its own basis. - A 1984Q1 prior passes 404.130(c) on 17 QCs. A 1986Q2 prior falls past age - 31, so with 1980's QCs gone it finds 16 of 40 and past blindness alone can - begin it. The two priors can rest on different bases in either order. + A 1984Q1 prior falls before age 31 and passes 404.130(c) on 17 QCs, but + unflagged it rests on past blindness alone. A 1985Q1 prior finds 20 of 40 + in 1980 to 1984. A 1986Q2 prior falls past age 31, so with 1980's QCs gone + it finds 16 of 40 and past blindness alone can begin it. The two priors can + rest on different bases in either order. """ case = basis_prior_declaration(seed) - if random.Random(f"two-basis-{seed}").random() < 0.5: - first = (date(1984, 1, 1), date(1984, 12, 31)) + draw = random.Random(f"two-basis-{seed}").random() + if draw < 2 / 3: + year = 1984 if draw < 1 / 3 else 1985 + first = (date(year, 1, 1), date(year, 12, 31)) return {**case, "prior": (first, *case["prior"])} first = (date(1986, 4, 1), date(1986, 12, 31)) annual = {year: n for year, n in case["annual"].items() if year != 1980} return {**case, "annual": annual, "prior": (first, *case["prior"])} +def young_basis_declaration(seed): + """The record before age 31, near the same edges. + + 404.130(c) can begin the 1998Q1 prior where 404.130(b) can't, and an + unflagged prior can't rest on it alone (404.130(d)(1)). Each draw moves + the years ``basis_prior_declaration`` moves, and a quarter of draws flag + the prior. + """ + case = basis_prior_declaration(seed) + flagged = random.Random(f"young-{seed}").random() < 0.25 + return { + **case, + "birth": YOUNG_PRIOR["birth"], + "annual": {y: n for y, n in case["annual"].items() if y > 1988}, + "special": flagged, + } + + +def mixed_flag_declaration(seed): + """A flagged prior, then an unflagged one before the onset. + + The later prior rests on past blindness, on 404.130(b), or after age 31 on + 404.130(d), which the flagged prior opens, and never on 404.130(c) alone + (404.130(d)(1)). Draws put its start on either side of age 31. A record + with no year between the flagged prior and the onset keeps one prior. + """ + case = subsequent_declaration(seed) + draw = random.Random(f"mixed-{seed}") + ((begins, ends),) = case["prior"] + years = range(ends.year + 1, case["onset"].year) + if not years: + return case + year = draw.choice(years) + later = (date(year, draw.choice((1, 4, 7, 10)), 1), date(year, 12, 31)) + return {**case, "prior": ((begins, ends), later), "flags": (True, False)} + + def special_prior_declaration(seed): """A flagged prior whose route and ordinary rule both turn on 1990.""" draw = random.Random(seed) @@ -1399,6 +1491,23 @@ def test_status_stress_a_flagged_prior_at_its_edge(seed): check_no_period(special_prior_declaration(seed)) +@settings(max_examples=30, deadline=None, derandomize=True) +@given(seed=st.integers(0, 2**32 - 1)) +def test_status_stress_a_young_prior_on_either_basis(seed): + case = young_basis_declaration(seed) + check_no_period(case) + check({**case, "onset": date(2004, 1, 15), "ending": date(2004, 12, 31)}) + + +@settings(max_examples=30, deadline=None, derandomize=True) +@given(seed=st.integers(0, 2**32 - 1)) +def test_status_stress_an_unflagged_prior_after_a_flagged_one(seed): + case = mixed_flag_declaration(seed) + assume(len(case["prior"]) == 2) + check(case) + check_no_period(case) + + # The same sweep found these two for UNKNOWN establishment. @settings(max_examples=30, deadline=None, derandomize=True) @example(seed=20, test=CURRENTLY) diff --git a/tests/tier_counts.json b/tests/tier_counts.json index f176c65bb..a3d3384e5 100644 --- a/tests/tier_counts.json +++ b/tests/tier_counts.json @@ -1,7 +1,7 @@ { "schema_version": 1, "counts": { - "unit": 25426, + "unit": 25445, "artifact": 4271, "integration_psid": 1471, "reproduction_legacy": 520, From 9d2db199705bb64d640ad775997e0145643d7310 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Tue, 3 Nov 2026 01:04:43 -0500 Subject: [PATCH 38/46] Record round 22's 70 cloud mutation kills (#562) Cloud brief 6562 ran round 22's 70 mutations at 7b5b126a through every insured status module (PR #562 comment 6596641719). All 70 failed a named test, and every run's open audit counted no restricted open. The ledger takes the records, the runner, the hashes of the six killing test modules and the replay steps; the design note gets one sentence. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 4 + .../track_b_insured_status_mutations.json | 1556 ++++++++++++++++- 2 files changed, 1559 insertions(+), 1 deletion(-) diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index fc57da609..f08e37c4c 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -3124,6 +3124,10 @@ first on `test_no_filling_carries_the_start_and_the_status_together`, and `test_unknown_period_status_and_dli_bounds_contain_concrete_fillings` kills `date_tested_at_query`. +A cloud session then ran all 70 at `7b5b126a`, through every insured status +module. All 70 failed a named test, with no restricted open +(`round_22_mutations`, PR #562 comment 6596641719). + Against `f37f7f79`, 13 of round 22's 17 tests fail, as do `test_status_stress_a_young_prior_on_either_basis` and round 21's `test_each_basis_matches_every_placement`. The four that pass check the diff --git a/docs/design/track_b_insured_status_mutations.json b/docs/design/track_b_insured_status_mutations.json index fcec21056..e234286e7 100644 --- a/docs/design/track_b_insured_status_mutations.json +++ b/docs/design/track_b_insured_status_mutations.json @@ -9759,5 +9759,1559 @@ "tests/test_track_b_insured_status_fix_round_2.py": "c1d00971949eb7d1f9ac458dfea1b5e47922fb3d0047a50a764e7400f9321835" }, "round_21_replay": "Write round_21_runner_source to scratch/review/run_round21_named.py. For each round_21_mutations record, write name/source_sha256/changes to its spec_path, then execute its exact command at f37f7f79. Mutations apply only in memory.", - "round_21_final_source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d" + "round_21_final_source_sha256": "380ef057bae23a6b425fdc7fa3ae91468ec4f0fe6f82ed0d102dd0d62c0fd20d", + "round_22_mutations": [ + { + "changes": [ + { + "after": " chosen = vacant[:count]\n", + "before": " chosen = vacant[-count:] if year == at.year else vacant[:count]\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-worst_always_early.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/worst_always_early /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_date_only_blindness_reaches_refuses[InsuredTest.DISABILITY]" + ], + "log": "scratch/review/round22-mutation-worst_always_early.log", + "name": "worst_always_early", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-worst_always_early.json" + }, + { + "changes": [ + { + "after": " chosen = vacant[-count:]\n", + "before": " chosen = vacant[-count:] if year == at.year else vacant[:count]\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-worst_always_late.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/worst_always_late /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_a_later_prior_on_an_earlier_endpoint_binds" + ], + "log": "scratch/review/round22-mutation-worst_always_late.log", + "name": "worst_always_late", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-worst_always_late.json" + }, + { + "changes": [ + { + "after": " if _witness(\n person,\n lower,\n person.disability_onset,\n coverage_end_month,\n InsuredTest.DISABILITY,\n )[0]:\n lo_start = hi_start = person.disability_onset\n", + "before": " if _start_fixed(\n person,\n lower,\n person.disability_onset,\n month,\n coverage_end_month,\n ):\n lo_start = hi_start = person.disability_onset\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-start_on_favorable_placement.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/start_on_favorable_placement /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_status_on_every_placement_computes" + ], + "log": "scratch/review/round22-mutation-start_on_favorable_placement.log", + "name": "start_on_favorable_placement", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-start_on_favorable_placement.json" + }, + { + "changes": [ + { + "after": "", + "before": " if prior_unknown or current_unknown:\n _settle_every_history(\n person, lower, month, coverage_end_month, decisions, dli\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-no_universal_proof.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/no_universal_proof /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_date[known_end]" + ], + "log": "scratch/review/round22-mutation-no_universal_proof.log", + "name": "no_universal_proof", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-no_universal_proof.json" + }, + { + "changes": [ + { + "after": " if prior_unknown:\n _settle_every_history(", + "before": " if prior_unknown or current_unknown:\n _settle_every_history(" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-proof_skips_open_period.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/proof_skips_open_period /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_unknown_establishment_alone_refuses[InsuredTest.ALL]" + ], + "log": "scratch/review/round22-mutation-proof_skips_open_period.log", + "name": "proof_skips_open_period", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-proof_skips_open_period.json" + }, + { + "changes": [ + { + "after": " if current_unknown:\n _settle_every_history(", + "before": " if prior_unknown or current_unknown:\n _settle_every_history(" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-proof_skips_unknown_priors.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/proof_skips_unknown_priors /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_date[known_end]" + ], + "log": "scratch/review/round22-mutation-proof_skips_unknown_priors.log", + "name": "proof_skips_unknown_priors", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-proof_skips_unknown_priors.json" + }, + { + "changes": [ + { + "after": " _settle_every_history(\n person, upper, month,", + "before": " _settle_every_history(\n person, lower, month," + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-proof_on_upper_credits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/proof_on_upper_credits /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_date[unknown_year]" + ], + "log": "scratch/review/round22-mutation-proof_on_upper_credits.log", + "name": "proof_on_upper_credits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-proof_on_upper_credits.json" + }, + { + "changes": [ + { + "after": " if (\n decision is not None\n and False\n and not _every_placement_passes(\n", + "before": " if (\n decision is not None\n and decision.insured\n and not _every_placement_passes(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-proof_skips_statuses.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/proof_skips_statuses /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_status[first_day-InsuredTest.ALL]" + ], + "log": "scratch/review/round22-mutation-proof_skips_statuses.log", + "name": "proof_skips_statuses", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-proof_skips_statuses.json" + }, + { + "changes": [ + { + "after": " if (\n dli is not None\n and False\n and not _every_placement_passes(\n", + "before": " if (\n dli is not None\n and dli.lower is not None\n and not _every_placement_passes(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-proof_skips_the_date.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/proof_skips_the_date /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_date[known_end]" + ], + "log": "scratch/review/round22-mutation-proof_skips_the_date.log", + "name": "proof_skips_the_date", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-proof_skips_the_date.json" + }, + { + "changes": [ + { + "after": " month,\n", + "before": " decision.qualifying_quarter,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-status_tested_at_query.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/status_tested_at_query /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_status_stands_at_the_quarter_it_reports" + ], + "log": "scratch/review/round22-mutation-status_tested_at_query.log", + "name": "status_tested_at_query", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-status_tested_at_query.json" + }, + { + "changes": [ + { + "after": " month,\n", + "before": " _qdate(_qid(dli.lower)),\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-date_tested_at_query.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/date_tested_at_query /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_2.py::test_unknown_period_status_and_dli_bounds_contain_concrete_fillings" + ], + "log": "scratch/review/round22-mutation-date_tested_at_query.log", + "name": "date_tested_at_query", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-date_tested_at_query.json" + }, + { + "changes": [ + { + "after": " bare = person\n for kind, decision", + "before": " bare = replace(person, prior_disability_periods=())\n for kind, decision" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-proof_keeps_listed_priors.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/proof_keeps_listed_priors /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_unknown_establishment_needs_the_disregard" + ], + "log": "scratch/review/round22-mutation-proof_keeps_listed_priors.log", + "name": "proof_keeps_listed_priors", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-proof_keeps_listed_priors.json" + }, + { + "changes": [ + { + "after": " if False\n", + "before": " if not current_unknown\n and _prior_start_binds(\n person, lower, upper, index, month, coverage_end_month, blind\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-no_listed_prior_check.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/no_listed_prior_check /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_date_only_blindness_reaches_refuses[InsuredTest.DISABILITY]" + ], + "log": "scratch/review/round22-mutation-no_listed_prior_check.log", + "name": "no_listed_prior_check", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-no_listed_prior_check.json" + }, + { + "changes": [ + { + "after": " if _prior_start_binds(\n person, lower, upper, index, month, coverage_end_month, blind\n )\n", + "before": " if not current_unknown\n and _prior_start_binds(\n person, lower, upper, index, month, coverage_end_month, blind\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-binding_reaches_open_period.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/binding_reaches_open_period /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_an_unknown_year_leaves_a_proven_result_to_the_proof" + ], + "log": "scratch/review/round22-mutation-binding_reaches_open_period.log", + "name": "binding_reaches_open_period", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-binding_reaches_open_period.json" + }, + { + "changes": [ + { + "after": " if False:\n", + "before": " if binding and unknown:\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-unknown_year_searches.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/unknown_year_searches /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_an_unknown_year_refuses" + ], + "log": "scratch/review/round22-mutation-unknown_year_searches.log", + "name": "unknown_year_searches", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-unknown_year_searches.json" + }, + { + "changes": [ + { + "after": " True\n or not (", + "before": " _prior_passes(person, filling, index, exit_month, blind=blind)\n and not (" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-keeps_every_filling.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/keeps_every_filling /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_date_only_blindness_reaches_refuses[InsuredTest.DISABILITY]" + ], + "log": "scratch/review/round22-mutation-keeps_every_filling.log", + "name": "keeps_every_filling", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-keeps_every_filling.json" + }, + { + "changes": [ + { + "after": "", + "before": " and not (\n person.prior_disability_periods[index].special_insured\n and _prior_passes(\n person,\n filling,\n index,\n exit_month,\n blind=False,\n ordinary_only=True,\n )\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-keeps_ignores_the_flag.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/keeps_ignores_the_flag /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_flagged_prior_there_computes" + ], + "log": "scratch/review/round22-mutation-keeps_ignores_the_flag.log", + "name": "keeps_ignores_the_flag", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-keeps_ignores_the_flag.json" + }, + { + "changes": [ + { + "after": "", + "before": " if not _keeps_priors(person, filling, binding, exit_month):\n continue\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-start_search_ignores_priors.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/start_search_ignores_priors /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_current_period_after_that_prior_refuses" + ], + "log": "scratch/review/round22-mutation-start_search_ignores_priors.log", + "name": "start_search_ignores_priors", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-start_search_ignores_priors.json" + }, + { + "changes": [ + { + "after": "", + "before": " if _keeps_priors(person, filling, binding, exit_month)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-listed_search_ignores_priors.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/listed_search_ignores_priors /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_date_only_blindness_reaches_refuses[InsuredTest.DISABILITY]" + ], + "log": "scratch/review/round22-mutation-listed_search_ignores_priors.log", + "name": "listed_search_ignores_priors", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-listed_search_ignores_priors.json" + }, + { + "changes": [ + { + "after": " year\n for index, _ in ()\n", + "before": " year\n for index, _ in binding\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-no_prior_years.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/no_prior_years /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_date_only_blindness_reaches_refuses[InsuredTest.DISABILITY]" + ], + "log": "scratch/review/round22-mutation-no_prior_years.log", + "name": "no_prior_years", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-no_prior_years.json" + }, + { + "changes": [ + { + "after": " )\n", + "before": " ) | _prior_sensitive_years(person, binding)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-start_search_skips_prior_years.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/start_search_skips_prior_years /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_reaches_a_year_the_start_cannot" + ], + "log": "scratch/review/round22-mutation-start_search_skips_prior_years.log", + "name": "start_search_skips_prior_years", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-start_search_skips_prior_years.json" + }, + { + "changes": [ + { + "after": " person, credits, start, month, exit_month, favored, ()\n ),\n start,\n", + "before": " person, credits, start, month, exit_month, favored, binding\n ),\n start,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-first_search_drops_binding.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/first_search_drops_binding /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_current_period_after_that_prior_refuses" + ], + "log": "scratch/review/round22-mutation-first_search_drops_binding.log", + "name": "first_search_drops_binding", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-first_search_drops_binding.json" + }, + { + "changes": [ + { + "after": " for filling, completed in _fillings_keeping_start(\n person, credits, start, month, exit_month, favored, ()\n", + "before": " for filling, completed in _fillings_keeping_start(\n person, credits, start, month, exit_month, favored, binding\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-date_search_drops_binding.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/date_search_drops_binding /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_listed_prior_holds_every_ending_to_the_date" + ], + "log": "scratch/review/round22-mutation-date_search_drops_binding.log", + "name": "date_search_drops_binding", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-date_search_drops_binding.json" + }, + { + "changes": [ + { + "after": "", + "before": " *((InsuredTest.DISABILITY,) if binding else ()),\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-disability_left_out_of_search.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/disability_left_out_of_search /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_limits_what_a_status_reports" + ], + "log": "scratch/review/round22-mutation-disability_left_out_of_search.log", + "name": "disability_left_out_of_search", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-disability_left_out_of_search.json" + }, + { + "changes": [ + { + "after": " option,\n", + "before": " person if kind is InsuredTest.DISABILITY else option,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-disability_reads_the_completion.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/disability_reads_the_completion /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_an_establishment_counts_no_quarter_of_its_own_period" + ], + "log": "scratch/review/round22-mutation-disability_reads_the_completion.log", + "name": "disability_reads_the_completion", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-disability_reads_the_completion.json" + }, + { + "changes": [ + { + "after": " dated=False,\n last_insured=last_insured,\n reported=reported,\n detail=\"Annual placement decides", + "before": " dated=dated,\n last_insured=last_insured,\n reported=reported,\n detail=\"Annual placement decides" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-listed_search_skips_the_date.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/listed_search_skips_the_date /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_flagged_prior_there_computes" + ], + "log": "scratch/review/round22-mutation-listed_search_skips_the_date.log", + "name": "listed_search_skips_the_date", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-listed_search_skips_the_date.json" + }, + { + "changes": [ + { + "after": " if not person.prior_disability_periods[index].special_insured:\n return True\n", + "before": " if not person.prior_disability_periods[index].special_insured:\n return not every\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-unflagged_refuses_every_placement.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/unflagged_refuses_every_placement /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_only_paragraph_b_binds_the_prior" + ], + "log": "scratch/review/round22-mutation-unflagged_refuses_every_placement.log", + "name": "unflagged_refuses_every_placement", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-unflagged_refuses_every_placement.json" + }, + { + "changes": [ + { + "after": " if True and not _every_placement_begins(\n person,\n lower,\n index,\n month,\n exit_month,\n blind=False,\n ordinary_only=True,\n ):\n", + "before": " if _prior_passes(\n person, upper, index, exit_month, blind=False\n ) and not _every_placement_begins(\n person,\n lower,\n index,\n month,\n exit_month,\n blind=False,\n ordinary_only=True,\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-flagged_ignores_support.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/flagged_ignores_support /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_flagged_prior_no_placement_supports_names_why[short_of_its_route]" + ], + "log": "scratch/review/round22-mutation-flagged_ignores_support.log", + "name": "flagged_ignores_support", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-flagged_ignores_support.json" + }, + { + "changes": [ + { + "after": " if _prior_passes(person, upper, index, exit_month, blind=False):\n", + "before": " if _prior_passes(\n person, upper, index, exit_month, blind=False\n ) and not _every_placement_begins(\n person,\n lower,\n index,\n month,\n exit_month,\n blind=False,\n ordinary_only=True,\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-flagged_ignores_ordinary_rule.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/flagged_ignores_ordinary_rule /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_flagged_prior_no_placement_supports_names_why[reaches_the_ordinary_rule]" + ], + "log": "scratch/review/round22-mutation-flagged_ignores_ordinary_rule.log", + "name": "flagged_ignores_ordinary_rule", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-flagged_ignores_ordinary_rule.json" + }, + { + "changes": [ + { + "after": " return True\n", + "before": " return not every or _prior_passes(\n person, upper, index, exit_month, blind=False, ordinary_only=True\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-flagged_refuses_every_placement.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/flagged_refuses_every_placement /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_an_unknown_year_leaves_a_special_prior_every_placement_carries" + ], + "log": "scratch/review/round22-mutation-flagged_refuses_every_placement.log", + "name": "flagged_refuses_every_placement", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-flagged_refuses_every_placement.json" + }, + { + "changes": [ + { + "after": " person, statutory_blindness=True, prior_disability_periods=()\n", + "before": " person, statutory_blindness=blind, prior_disability_periods=()\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-every_flagged_reads_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/every_flagged_reads_blindness /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_date_only_blindness_reaches_refuses[InsuredTest.DISABILITY]" + ], + "log": "scratch/review/round22-mutation-every_flagged_reads_blindness.log", + "name": "every_flagged_reads_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-every_flagged_reads_blindness.json" + }, + { + "changes": [ + { + "after": " person, statutory_blindness=False, prior_disability_periods=()\n", + "before": " person, statutory_blindness=blind, prior_disability_periods=()\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-every_unflagged_reads_no_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/every_unflagged_reads_no_blindness /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_only_paragraph_b_binds_the_prior" + ], + "log": "scratch/review/round22-mutation-every_unflagged_reads_no_blindness.log", + "name": "every_unflagged_reads_no_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-every_unflagged_reads_no_blindness.json" + }, + { + "changes": [ + { + "after": " statutory_blindness=True,\n prior_disability_periods=person.prior_disability_periods[:index],\n", + "before": " statutory_blindness=blind,\n prior_disability_periods=person.prior_disability_periods[:index],\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-route_flagged_reads_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/route_flagged_reads_blindness /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_date_only_blindness_reaches_refuses[InsuredTest.DISABILITY]" + ], + "log": "scratch/review/round22-mutation-route_flagged_reads_blindness.log", + "name": "route_flagged_reads_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-route_flagged_reads_blindness.json" + }, + { + "changes": [ + { + "after": " statutory_blindness=False,\n prior_disability_periods=person.prior_disability_periods[:index],\n", + "before": " statutory_blindness=blind,\n prior_disability_periods=person.prior_disability_periods[:index],\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-route_unflagged_reads_no_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/route_unflagged_reads_no_blindness /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_prior_only_paragraph_c_begins_rests_on_past_blindness" + ], + "log": "scratch/review/round22-mutation-route_unflagged_reads_no_blindness.log", + "name": "route_unflagged_reads_no_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-route_unflagged_reads_no_blindness.json" + }, + { + "changes": [ + { + "after": " person,\n statutory_blindness=blind,\n prior_disability_periods=person.prior_disability_periods[:index],\n", + "before": " person, statutory_blindness=blind, prior_disability_periods=()\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-every_reads_listed_periods.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/every_reads_listed_periods /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_a_later_prior_on_an_earlier_endpoint_binds" + ], + "log": "scratch/review/round22-mutation-every_reads_listed_periods.log", + "name": "every_reads_listed_periods", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-every_reads_listed_periods.json" + }, + { + "changes": [ + { + "after": " prior_disability_periods=(),\n )\n return _witness(\n", + "before": " prior_disability_periods=person.prior_disability_periods[:index],\n )\n return _witness(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-some_drops_earlier_periods.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/some_drops_earlier_periods /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_prior_past_31_after_a_flagged_one_can_rest_on_paragraph_d" + ], + "log": "scratch/review/round22-mutation-some_drops_earlier_periods.log", + "name": "some_drops_earlier_periods", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-some_drops_earlier_periods.json" + }, + { + "changes": [ + { + "after": " every = _every_placement_begins(\n person, upper, index, month, exit_month, blind=blind\n )\n", + "before": " every = _every_placement_begins(\n person, lower, index, month, exit_month, blind=blind\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-every_on_upper_credits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/every_on_upper_credits /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_an_unknown_year_can_support_a_prior" + ], + "log": "scratch/review/round22-mutation-every_on_upper_credits.log", + "name": "every_on_upper_credits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-every_on_upper_credits.json" + }, + { + "changes": [ + { + "after": " for blind in (False, True):\n if _prior_passes(person, lower, index, exit_month, blind=blind):\n return blind\n", + "before": " for blind in (False, True):\n if _prior_passes(person, upper, index, exit_month, blind=blind):\n return blind\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-some_on_lower_credits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/some_on_lower_credits /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_an_unknown_year_can_support_a_prior" + ], + "log": "scratch/review/round22-mutation-some_on_lower_credits.log", + "name": "some_on_lower_credits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-some_on_lower_credits.json" + }, + { + "changes": [ + { + "after": " if (\n young and under31_route or subsequent and not young\n ):\n", + "before": " if not ordinary_only and (\n young and under31_route or subsequent and not young\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-ordinary_keeps_special_route.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/ordinary_keeps_special_route /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_flagged_prior_there_computes" + ], + "log": "scratch/review/round22-mutation-ordinary_keeps_special_route.log", + "name": "ordinary_keeps_special_route", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-ordinary_keeps_special_route.json" + }, + { + "changes": [ + { + "after": " person,\n person.disability_onset,\n _current_period_start_horizon(person, month),\n ) | _prior_sensitive_years(person, binding)\n", + "before": " person, person.disability_onset, start\n ) | _prior_sensitive_years(person, binding)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-fix_reverted.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/fix_reverted /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_partial_years_after_the_start_stay_open" + ], + "log": "scratch/review/round22-mutation-fix_reverted.log", + "name": "fix_reverted", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-fix_reverted.json" + }, + { + "changes": [ + { + "after": " for blind in (True,):\n if _prior_passes(person, upper, index, exit_month, blind=blind):\n return blind\n", + "before": " for blind in (False, True):\n if _prior_passes(person, upper, index, exit_month, blind=blind):\n return blind\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-basis_always_blind.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/basis_always_blind /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_date_only_blindness_reaches_refuses[InsuredTest.DISABILITY]" + ], + "log": "scratch/review/round22-mutation-basis_always_blind.log", + "name": "basis_always_blind", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-basis_always_blind.json" + }, + { + "changes": [ + { + "after": " for blind in (False,):\n if _prior_passes(person, upper, index, exit_month, blind=blind):\n return blind\n", + "before": " for blind in (False, True):\n if _prior_passes(person, upper, index, exit_month, blind=blind):\n return blind\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-basis_always_nonblind.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/basis_always_nonblind /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_prior_only_paragraph_c_begins_rests_on_past_blindness" + ], + "log": "scratch/review/round22-mutation-basis_always_nonblind.log", + "name": "basis_always_nonblind", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-basis_always_nonblind.json" + }, + { + "changes": [ + { + "after": " every = _every_placement_begins(\n person, lower, index, month, exit_month, blind=True\n )\n", + "before": " every = _every_placement_begins(\n person, lower, index, month, exit_month, blind=blind\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-binds_ignores_basis.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/binds_ignores_basis /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_date_only_blindness_reaches_refuses[InsuredTest.DISABILITY]" + ], + "log": "scratch/review/round22-mutation-binds_ignores_basis.log", + "name": "binds_ignores_basis", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-binds_ignores_basis.json" + }, + { + "changes": [ + { + "after": " every = _every_placement_begins(\n person, lower, index, month, exit_month, blind=False\n )\n", + "before": " every = _every_placement_begins(\n person, lower, index, month, exit_month, blind=blind\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-binds_always_nonblind.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/binds_always_nonblind /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_only_paragraph_b_binds_the_prior" + ], + "log": "scratch/review/round22-mutation-binds_always_nonblind.log", + "name": "binds_always_nonblind", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-binds_always_nonblind.json" + }, + { + "changes": [ + { + "after": " _prior_passes(person, filling, index, exit_month, blind=True)\n and not (", + "before": " _prior_passes(person, filling, index, exit_month, blind=blind)\n and not (" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-keeps_ignores_basis.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/keeps_ignores_basis /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_date_only_blindness_reaches_refuses[InsuredTest.DISABILITY]" + ], + "log": "scratch/review/round22-mutation-keeps_ignores_basis.log", + "name": "keeps_ignores_basis", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-keeps_ignores_basis.json" + }, + { + "changes": [ + { + "after": " _prior_passes(person, filling, index, exit_month, blind=False)\n and not (", + "before": " _prior_passes(person, filling, index, exit_month, blind=blind)\n and not (" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-keeps_always_nonblind.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/keeps_always_nonblind /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_only_paragraph_b_binds_the_prior" + ], + "log": "scratch/review/round22-mutation-keeps_always_nonblind.log", + "name": "keeps_always_nonblind", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-keeps_always_nonblind.json" + }, + { + "changes": [ + { + "after": " return True\n", + "before": " _refuse(\n InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY,\n \"No annual placement supports a listed prior's first insured quarter\",\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-no_support_stands.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/no_support_stands /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_prior_no_placement_supports_refuses_for_each_test[InsuredTest.ALL]" + ], + "log": "scratch/review/round22-mutation-no_support_stands.log", + "name": "no_support_stands", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-no_support_stands.json" + }, + { + "changes": [ + { + "after": " if _prior_passes(\n person, upper, index, exit_month, blind=True\n ) and not _every_placement_begins(\n person,\n lower,\n index,\n month,\n exit_month,\n blind=False,\n ordinary_only=True,\n ):\n", + "before": " if _prior_passes(\n person, upper, index, exit_month, blind=False\n ) and not _every_placement_begins(\n person,\n lower,\n index,\n month,\n exit_month,\n blind=False,\n ordinary_only=True,\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-flagged_support_reads_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/flagged_support_reads_blindness /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_flagged_prior_no_placement_supports_names_why[short_of_its_route]" + ], + "log": "scratch/review/round22-mutation-flagged_support_reads_blindness.log", + "name": "flagged_support_reads_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-flagged_support_reads_blindness.json" + }, + { + "changes": [ + { + "after": " if _prior_passes(\n person, upper, index, exit_month, blind=False\n ) and not _every_placement_begins(\n person,\n lower,\n index,\n month,\n exit_month,\n blind=True,\n ordinary_only=True,\n ):\n", + "before": " if _prior_passes(\n person, upper, index, exit_month, blind=False\n ) and not _every_placement_begins(\n person,\n lower,\n index,\n month,\n exit_month,\n blind=False,\n ordinary_only=True,\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-flagged_ordinary_reads_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/flagged_ordinary_reads_blindness /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_flagged_prior_there_computes" + ], + "log": "scratch/review/round22-mutation-flagged_ordinary_reads_blindness.log", + "name": "flagged_ordinary_reads_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-flagged_ordinary_reads_blindness.json" + }, + { + "changes": [ + { + "after": " if _prior_passes(\n person, lower, index, exit_month, blind=False\n ) and not _every_placement_begins(\n person,\n lower,\n index,\n month,\n exit_month,\n blind=False,\n ordinary_only=True,\n ):\n", + "before": " if _prior_passes(\n person, upper, index, exit_month, blind=False\n ) and not _every_placement_begins(\n person,\n lower,\n index,\n month,\n exit_month,\n blind=False,\n ordinary_only=True,\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-flagged_support_on_lower_credits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/flagged_support_on_lower_credits /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_an_unknown_year_can_leave_a_flagged_prior_short_of_the_ordinary_rule" + ], + "log": "scratch/review/round22-mutation-flagged_support_on_lower_credits.log", + "name": "flagged_support_on_lower_credits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-flagged_support_on_lower_credits.json" + }, + { + "changes": [ + { + "after": " if _prior_passes(\n person, upper, index, exit_month, blind=False\n ) and not _every_placement_begins(\n person,\n upper,\n index,\n month,\n exit_month,\n blind=False,\n ordinary_only=True,\n ):\n", + "before": " if _prior_passes(\n person, upper, index, exit_month, blind=False\n ) and not _every_placement_begins(\n person,\n lower,\n index,\n month,\n exit_month,\n blind=False,\n ordinary_only=True,\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-flagged_ordinary_on_upper_credits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/flagged_ordinary_on_upper_credits /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_an_unknown_year_can_carry_a_flagged_prior_past_the_ordinary_rule" + ], + "log": "scratch/review/round22-mutation-flagged_ordinary_on_upper_credits.log", + "name": "flagged_ordinary_on_upper_credits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-flagged_ordinary_on_upper_credits.json" + }, + { + "changes": [ + { + "after": " bases = tuple(\n _prior_basis(person, lower, upper, index, month, coverage_end_month)\n for index in range(0 if current_unknown else len(person.prior_disability_periods))\n )\n", + "before": " bases = tuple(\n _prior_basis(person, lower, upper, index, month, coverage_end_month)\n for index in range(len(person.prior_disability_periods))\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-basis_skipped_on_open_period.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/basis_skipped_on_open_period /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_unknown_establishment_refuses_a_prior_no_placement_supports" + ], + "log": "scratch/review/round22-mutation-basis_skipped_on_open_period.log", + "name": "basis_skipped_on_open_period", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-basis_skipped_on_open_period.json" + }, + { + "changes": [ + { + "after": " (index, True)\n for index, blind in enumerate(bases)\n", + "before": " (index, blind)\n for index, blind in enumerate(bases)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-binding_pair_drops_basis.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/binding_pair_drops_basis /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_date_only_blindness_reaches_refuses[InsuredTest.DISABILITY]" + ], + "log": "scratch/review/round22-mutation-binding_pair_drops_basis.log", + "name": "binding_pair_drops_basis", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-binding_pair_drops_basis.json" + }, + { + "changes": [ + { + "after": " bases = tuple(\n _prior_basis(person, lower, upper, index, month, coverage_end_month)\n for index in range(len(person.prior_disability_periods) if test in (InsuredTest.ALL, InsuredTest.DISABILITY) else 0)\n )\n", + "before": " bases = tuple(\n _prior_basis(person, lower, upper, index, month, coverage_end_month)\n for index in range(len(person.prior_disability_periods))\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-basis_only_on_disability.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/basis_only_on_disability /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_a_prior_no_placement_supports_refuses_for_each_test[InsuredTest.FULLY]" + ], + "log": "scratch/review/round22-mutation-basis_only_on_disability.log", + "name": "basis_only_on_disability", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-basis_only_on_disability.json" + }, + { + "changes": [ + { + "after": " return not every or _prior_passes(\n person, upper, index, exit_month, blind=True, ordinary_only=True\n )\n", + "before": " return not every or _prior_passes(\n person, upper, index, exit_month, blind=False, ordinary_only=True\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-binds_flag_reads_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/binds_flag_reads_blindness /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_an_unknown_year_leaves_a_special_prior_every_placement_carries" + ], + "log": "scratch/review/round22-mutation-binds_flag_reads_blindness.log", + "name": "binds_flag_reads_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-binds_flag_reads_blindness.json" + }, + { + "changes": [ + { + "after": " return not every or _prior_passes(\n person, lower, index, exit_month, blind=False, ordinary_only=True\n )\n", + "before": " return not every or _prior_passes(\n person, upper, index, exit_month, blind=False, ordinary_only=True\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-binds_flag_on_lower_credits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/binds_flag_on_lower_credits /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_an_unknown_year_can_carry_a_flagged_prior_past_the_ordinary_rule" + ], + "log": "scratch/review/round22-mutation-binds_flag_on_lower_credits.log", + "name": "binds_flag_on_lower_credits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-binds_flag_on_lower_credits.json" + }, + { + "changes": [ + { + "after": " exit_month,\n blind=True,\n ordinary_only=True,\n", + "before": " exit_month,\n blind=False,\n ordinary_only=True,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-keeps_flag_reads_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/keeps_flag_reads_blindness /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_flagged_prior_there_computes" + ], + "log": "scratch/review/round22-mutation-keeps_flag_reads_blindness.log", + "name": "keeps_flag_reads_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-keeps_flag_reads_blindness.json" + }, + { + "changes": [ + { + "after": " if binding:\n favored_rows, _ = _world(", + "before": " if lo_start is not None or binding:\n favored_rows, _ = _world(" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-remove_first_start_check.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/remove_first_start_check /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[109307]" + ], + "log": "scratch/review/round22-mutation-remove_first_start_check.log", + "name": "remove_first_start_check", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-remove_first_start_check.json" + }, + { + "changes": [ + { + "after": " if False and any(\n _improves(outcome, returned, last_insured)\n for outcome in _period_outcomes(", + "before": " if any(\n _improves(outcome, returned, last_insured)\n for outcome in _period_outcomes(" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-drop_bound_refusal.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/drop_bound_refusal /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[109307]" + ], + "log": "scratch/review/round22-mutation-drop_bound_refusal.log", + "name": "drop_bound_refusal", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-drop_bound_refusal.json" + }, + { + "changes": [ + { + "after": " \"dated\": False,\n \"last_insured\": None,\n", + "before": " \"dated\": dli is not None,\n \"last_insured\": dli.upper if dli is not None else None,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-drop_dli_comparison.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/drop_dli_comparison /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_frozen_exit_refuses" + ], + "log": "scratch/review/round22-mutation-drop_dli_comparison.log", + "name": "drop_dli_comparison", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-drop_dli_comparison.json" + }, + { + "changes": [ + { + "after": " return _every_placement_passes(\n person, credits, start, month, exit_month, InsuredTest.DISABILITY\n )", + "before": " return not person.prior_disability_periods and _every_placement_passes(\n person, credits, start, month, exit_month, InsuredTest.DISABILITY\n )" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-start_fixed_ignores_priors.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/start_fixed_ignores_priors /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_current_period_after_that_prior_refuses" + ], + "log": "scratch/review/round22-mutation-start_fixed_ignores_priors.log", + "name": "start_fixed_ignores_priors", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-start_fixed_ignores_priors.json" + }, + { + "changes": [ + { + "after": " horizon = _current_period_start_horizon(person, month)\n for quarter in range(_qid(start), _qid(start) + 1):\n try:\n completed, own_start = _complete_current_period(", + "before": " horizon = _current_period_start_horizon(person, month)\n for quarter in range(_qid(start), _qid(horizon) + 1):\n try:\n completed, own_start = _complete_current_period(" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-bound_stops_at_reported_start.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/bound_stops_at_reported_start /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[109307]" + ], + "log": "scratch/review/round22-mutation-bound_stops_at_reported_start.log", + "name": "bound_stops_at_reported_start", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-bound_stops_at_reported_start.json" + }, + { + "changes": [ + { + "after": " if not ordinary_only and (\n young or subsequent and not young\n ):\n", + "before": " if not ordinary_only and (\n young and under31_route or subsequent and not young\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-unflagged_reads_paragraph_c.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/unflagged_reads_paragraph_c /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_date_only_blindness_reaches_refuses[InsuredTest.DISABILITY]" + ], + "log": "scratch/review/round22-mutation-unflagged_reads_paragraph_c.log", + "name": "unflagged_reads_paragraph_c", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-unflagged_reads_paragraph_c.json" + }, + { + "changes": [ + { + "after": " if not ordinary_only and (\n young and under31_route or subsequent\n ):\n", + "before": " if not ordinary_only and (\n young and under31_route or subsequent and not young\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-young_takes_subsequent_route.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/young_takes_subsequent_route /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_young_prior_after_a_flagged_one_rests_on_paragraph_b" + ], + "log": "scratch/review/round22-mutation-young_takes_subsequent_route.log", + "name": "young_takes_subsequent_route", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-young_takes_subsequent_route.json" + }, + { + "changes": [ + { + "after": " if not ordinary_only and (\n under31_route and (young or subsequent)\n ):\n", + "before": " if not ordinary_only and (\n young and under31_route or subsequent and not young\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-unflagged_drops_paragraph_d.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/unflagged_drops_paragraph_d /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_prior_past_31_after_a_flagged_one_can_rest_on_paragraph_d" + ], + "log": "scratch/review/round22-mutation-unflagged_drops_paragraph_d.log", + "name": "unflagged_drops_paragraph_d", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-unflagged_drops_paragraph_d.json" + }, + { + "changes": [ + { + "after": " InsuredTest.DISABILITY,\n under31_route=True,\n **options,\n )[0]\n", + "before": " InsuredTest.DISABILITY,\n under31_route=period.special_insured,\n **options,\n )[0]\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-route_reads_paragraph_c.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/route_reads_paragraph_c /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_date_only_blindness_reaches_refuses[InsuredTest.DISABILITY]" + ], + "log": "scratch/review/round22-mutation-route_reads_paragraph_c.log", + "name": "route_reads_paragraph_c", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-route_reads_paragraph_c.json" + }, + { + "changes": [ + { + "after": " InsuredTest.DISABILITY,\n under31_route=True,\n **options,\n )\n\n", + "before": " InsuredTest.DISABILITY,\n under31_route=period.special_insured,\n **options,\n )\n\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-every_reads_paragraph_c.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/every_reads_paragraph_c /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_date_only_blindness_reaches_refuses[InsuredTest.DISABILITY]" + ], + "log": "scratch/review/round22-mutation-every_reads_paragraph_c.log", + "name": "every_reads_paragraph_c", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-every_reads_paragraph_c.json" + }, + { + "changes": [ + { + "after": " InsuredTest.DISABILITY,\n under31_route=False,\n **options,\n )[0]\n", + "before": " InsuredTest.DISABILITY,\n under31_route=period.special_insured,\n **options,\n )[0]\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-route_drops_flagged_paragraph_c.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/route_drops_flagged_paragraph_c /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_flagged_prior_there_computes" + ], + "log": "scratch/review/round22-mutation-route_drops_flagged_paragraph_c.log", + "name": "route_drops_flagged_paragraph_c", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-route_drops_flagged_paragraph_c.json" + }, + { + "changes": [ + { + "after": " InsuredTest.DISABILITY,\n under31_route=False,\n **options,\n )\n\n", + "before": " InsuredTest.DISABILITY,\n under31_route=period.special_insured,\n **options,\n )\n\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-every_drops_flagged_paragraph_c.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/every_drops_flagged_paragraph_c /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_an_unknown_year_can_carry_a_flagged_prior_past_the_ordinary_rule" + ], + "log": "scratch/review/round22-mutation-every_drops_flagged_paragraph_c.log", + "name": "every_drops_flagged_paragraph_c", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-every_drops_flagged_paragraph_c.json" + }, + { + "changes": [ + { + "after": " ordinary_only=False,\n under31_route=False,\n):\n", + "before": " ordinary_only=False,\n under31_route=True,\n):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round22 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round22 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND22_MUTATION=scratch/review/round22-mutation-current_drops_paragraph_c.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp22/current_drops_paragraph_c /tmp/tbvenv/bin/python scratch/review/run_round22_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_holds_a_qc_in_its_first_quarter" + ], + "log": "scratch/review/round22-mutation-current_drops_paragraph_c.log", + "name": "current_drops_paragraph_c", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "spec_path": "scratch/review/round22-mutation-current_drops_paragraph_c.json" + } + ], + "round_22_runner_source": "\"\"\"Run named invented-data conformance tests with open-event auditing.\"\"\"\n\nimport hashlib\nimport json\nimport os\nfrom pathlib import Path\nimport sys\n\nCOUNTS = {\"restricted_opens\": 0, \"subprocess.Popen\": 0, \"os.system\": 0}\nBARRED = {\n \"gates.yaml\", \"adjusted_poverty.py\", \"rows.py\",\n \"ssa_trust_fund_interest_rates_2026.json\",\n \"urban2010_cola_comparison.md\", \"urban2010_fra68_comparison.md\",\n \"boomers2004_uniform_cut_comparison.md\", \"minimum_benefits_comparison.md\",\n \"m6_projection_engine.md\", \"mint8_table_user_guide.source.html\",\n \"test_anchor_provenance_erratum.py\",\n \"s0_1_power_results.json\", \"s0_1_source_audit.md\", \"s0_1_power.py\",\n \"test_s0_1_invariants.py\", \"test_s0_1_power.py\",\n \"test_s0_1_thresholds.py\",\n}\n\n\ndef audit(event, arguments):\n if event == \"open\" and isinstance(arguments[0], (str, bytes)):\n path = os.fsdecode(arguments[0])\n name = Path(path).name\n if (\n name in BARRED\n or name.startswith((\"adjusted_poverty.\", \"rows.\"))\n or \"/PolicyEngine/psid-data/\" in path\n or \"/microcosm-launch-evidence/\" in path\n or \"/dynasim-refs/\" in path\n or \"/claude-501/\" in path\n or \"/tests/s0_1/\" in path\n or \"/tests/acola_track/\" in path\n or \"/tests/cola_track_a/\" in path\n or \"/tests/fra68_track/\" in path\n ):\n COUNTS[\"restricted_opens\"] += 1\n raise RuntimeError(path)\n elif event in (\"subprocess.Popen\", \"os.system\"):\n COUNTS[event] += 1\n\n\ndef main():\n for name in (\"POPULACE_DYNAMICS_PSID_DIR\", \"POPULACE_DYNAMICS_EPUF_DIR\"):\n assert os.environ[name] == \"/nonexistent/trackb-round22\"\n assert sys.argv[1:]\n assert all(\n not argument.startswith(\"tests/\") or \".py\" in argument\n for argument in sys.argv[1:]\n )\n sys.addaudithook(audit)\n from populace_dynamics.track_b import insured_status as insured\n\n source_path = Path(insured.__file__)\n original = source_path.read_bytes()\n baseline_path = os.environ.get(\"TRACKB_ROUND16_SOURCE\")\n if baseline_path:\n baseline = Path(baseline_path).read_bytes()\n exec(compile(baseline, str(source_path), \"exec\"), insured.__dict__)\n print(\"BASELINE\", hashlib.sha256(baseline).hexdigest(), flush=True)\n spec_path = os.environ.get(\"TRACKB_ROUND22_MUTATION\")\n if spec_path:\n spec = json.loads(Path(spec_path).read_text())\n assert hashlib.sha256(original).hexdigest() == spec[\"source_sha256\"]\n source = original.decode()\n for change in spec[\"changes\"]:\n assert source.count(change[\"before\"]) == 1, change[\"before\"]\n source = source.replace(change[\"before\"], change[\"after\"], 1)\n exec(compile(source, str(source_path), \"exec\"), insured.__dict__)\n print(\"MUTATION\", spec[\"name\"], flush=True)\n import pytest\n\n try:\n return pytest.main(sys.argv[1:])\n finally:\n assert source_path.read_bytes() == original\n print(\"OPEN_AUDIT\", json.dumps(COUNTS, sort_keys=True), flush=True)\n\n\nif __name__ == \"__main__\":\n raise SystemExit(main())\n", + "round_22_note": "A cloud session ran round 22's 70 mutations at 7b5b126a, the final round 22 source and test bytes, against every insured status module, with no restricted open (PR #562 comment 6596641719). The 70 are round 21's 62, with ordinary_keeps_special_route re-derived against round 22's condition, and eight of round 22's own. All 70 failed a named test.", + "round_22_test_sha256": { + "tests/test_track_b_insured_status_fix_round_22.py": "60d3b6614ef2363eb16b7bac7a83b46a6d1848270b66dde116b6acd5d781a55a", + "tests/test_track_b_insured_status_fix_round_21.py": "dd858c630cbd0473745568cdcf92ac28b350bd4efe06e35f5be1f4c264b3aa04", + "tests/test_track_b_insured_status_fix_round_19.py": "735433c50e252f3bfcdc4c11019c52d750ddfe97dbb3195d3e51bff511175b59", + "tests/test_track_b_insured_status_status_stress.py": "ae355dd995d9b1eb13863b3e790538bf827f5e2034424e9e0344b572aa91cd4c", + "tests/test_track_b_insured_status_fix_round_20.py": "f15ef8610de8fb6138f485588ff188c6748e34ebd5cb51ee2f55735d2fa9c4cd", + "tests/test_track_b_insured_status_fix_round_2.py": "c1d00971949eb7d1f9ac458dfea1b5e47922fb3d0047a50a764e7400f9321835" + }, + "round_22_replay": "Write round_22_runner_source to scratch/review/run_round22_named.py. For each round_22_mutations record, write name/source_sha256/changes to its spec_path, then execute its exact command at 7b5b126a. Mutations apply only in memory.", + "round_22_final_source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880" } From 8522452c7e2d1d468fcee4658026a6a832f78910 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Tue, 3 Nov 2026 05:22:00 -0500 Subject: [PATCH 39/46] Flag 404.130(c)-only current periods; share quarters (#562 round 23) An independent review of 7b5b126a asked for changes on seven mediums, 17 lows and six nits (PR comment 6596920658). A current period the rule began before 31 on 404.130(c) alone now carries the 404.130(d)(1) flag for the quarters after it, so the review's record (born 1980-02-02) gets a date last insured of 2012-12-31 where 7b5b126a gave 2006-06-30. Where placement or an UNKNOWN year decides that basis and the dates differ, the date refuses by name. Periods may share a quarter but not a day (404.321(a); RS 00301.140 example 7), so the overlap search, I13, B15 and the flag-first-insured-quarter register entry go. An exit or a birth bars no quarter of its own year (RS 00301.230 B). DISABILITY reports the earliest first insured quarter a kept filling attains; its range spans a binding prior's bases, naming prior_disability_period_basis, and reaches the onset quarter under UNKNOWN priors. A living man born before 1913 counts elapsed years to 65 or 1975 (404.110(b)(2)(iii)-(iv)). A flagged prior needs one placement that passes a special route and fails 404.130(b). A listed prior no completion supports refuses before any input error, past blindness begins a listed prior only from 1973, and a listed pre-1956 prior can rest on RS 00301.480 B.1. Lows 12, 16, 19, 23 and 24 and nit 25 change code, each with a test. The design note answers the rest and records round 23, its renames and retirements, and the 99 mutations with their local kills. The tier counts add 80 unit tests. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 805 +++++++--- .../track_b/_insured_status_qc.py | 13 +- .../track_b/insured_status.py | 1118 ++++++++------ tests/README-tiers.md | 2 +- .../data/track_b/insured_status_examples.yaml | 35 +- .../track_b/insured_status_sources/README.md | 27 +- tests/test_track_b_insured_status.py | 33 +- ..._b_insured_status_classification_oracle.py | 269 +++- tests/test_track_b_insured_status_contract.py | 4 +- ...est_track_b_insured_status_fix_round_10.py | 23 +- ...est_track_b_insured_status_fix_round_11.py | 44 +- ...est_track_b_insured_status_fix_round_12.py | 47 +- ...est_track_b_insured_status_fix_round_13.py | 75 +- ...est_track_b_insured_status_fix_round_14.py | 232 ++- ...est_track_b_insured_status_fix_round_17.py | 8 +- ...est_track_b_insured_status_fix_round_22.py | 5 +- ...est_track_b_insured_status_fix_round_23.py | 1299 +++++++++++++++++ ...ack_b_insured_status_fix_round_4_routes.py | 44 +- ..._insured_status_fix_round_5_possibility.py | 53 +- ...k_b_insured_status_fix_round_6_ordering.py | 34 +- ...ack_b_insured_status_fix_round_6_routes.py | 95 +- ...test_track_b_insured_status_fix_round_8.py | 8 + tests/test_track_b_insured_status_qc.py | 14 +- tests/test_track_b_insured_status_sources.py | 23 +- ...st_track_b_insured_status_status_oracle.py | 18 +- ...st_track_b_insured_status_status_stress.py | 38 +- tests/tier_counts.json | 2 +- 27 files changed, 3426 insertions(+), 942 deletions(-) create mode 100644 tests/test_track_b_insured_status_fix_round_23.py diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index f08e37c4c..496885e4d 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -49,7 +49,10 @@ Currently insured uses the supplied death date, RIB entitlement month, or most recent DIB entitlement month when available; any qualifying event suffices. With none supplied it tests a hypothetical event in the query quarter (214(b); RS 00301.110). Actual event dates are retained in later -queries; an emigrant with no entitlement event continues on the query clock. +queries, so a declared past DIB or RIB month replaces the query event even +where the worker has earned QCs since, and the result answers for the +declared event (round 23 states this). An emigrant with no entitlement +event continues on the query clock. Every established period intersecting that event's 13-quarter window is considered, including a period containing or extending beyond the event. The credited first and last quarters remain eligible (404.120(b); RS .110). @@ -89,7 +92,11 @@ lifetime QCs cannot insure a worker whether section 214(c) applies or not. A `DisabilityPeriod` declares `start`, `end`, and `special_insured`: the latter is an adjudicated fact that the earlier period qualified only under the special young-worker test. -Periods must not overlap calendar quarters. The ordered period sequence has +Periods must not share a day; each begins after the one before it ends. +A period may begin in the quarter the one before ended (404.321(a); +RS 00301.140 example 7), and that quarter is then an endpoint quarter of +both, which 404.146(d)(1) lets be a QC and 404.130(f) counts where it is +one (round 23). The ordered period sequence has `prior_disability_periods_provenance` and optional `prior_disability_periods_convention_id`; an observed empty sequence explicitly means no established periods. The default provenance is @@ -200,20 +207,17 @@ a universal exclusion of that route for DISABILITY. If some feasible fillings still lack 20/40, application facts remain absent and the alternate possibility retains its refusal. On the ordinary route, a valid -filling must supply one insured start that is at or before the applicable -recovery or administrative-end bound and clears every prior-period overlap. -A later witness at the query cannot rescue an immutable earlier bound. The -scan therefore stops at that bound, any continuity observation, death, or -FRA cap, whichever is earlier. Maximum credits decide the monotone -insured-by-that-date question. If that representative's derived start overlaps a prior period, -the rule checks lower-credit fillings and, when needed, enumerates the -bounded concrete fillings for a single valid period. It never combines -the end compliance of one filling with the overlap compliance of another. -Before that enumeration, it checks whether any candidate starting quarter -from onset through the fixed horizon clears all supplied prior periods. -If none does, no credit route can supply a nonoverlapping start. +filling must supply one insured start at or before the applicable +recovery or administrative-end bound. A later witness at the query cannot +rescue an immutable earlier bound. The scan therefore stops at that bound, +any continuity observation, death, or FRA cap, whichever is earlier. +Maximum credits decide the monotone insured-by-that-date question. Every +prior period ends before onset, and a period may begin in the quarter a +prior ended, so no derived start overlaps a prior period (round 23). Only when all routes and feasible fillings are impossible can the rule -raise `InvalidFamilyInput` before any coverage refusal. On the ordinary +raise `InvalidFamilyInput` before any coverage refusal, and a listed prior +that no completion supports refuses by name first (round 23; see the +refusal order below). On the ordinary supported QC surface, fewer than six maximum feasible lifetime QCs proves impossibility: 404.130(a) requires fully insured status, and 404.110(b)(1) says, "You need at least 6 QCs but @@ -223,8 +227,8 @@ transitional, military, railroad, or other specialist routes. A flag or observable specialist route that could validate the declaration prevents that input error and preserves a refusal row. -After the fixed-quarter overlap check, declared foreign credits preserve -their unmodeled route before every credit-count proof. Credit-route flags, +Declared foreign credits preserve their unmodeled route before every +credit-count proof. Credit-route flags, or raw-earnings flags without a complete direct-QC envelope, do likewise. The flag classes and their captured premises are listed below. The minimum-requirement proof precedes every recent-rule or alternate scan, @@ -254,15 +258,14 @@ flag alone bypasses this proof because 404.130(e) has no recent-credit test and the flag presumes its fully insured prerequisite. Blindness without that flag still needs six ordinary fully insured QCs. With known prior history, a nonblind fully-route flag also needs a -possible recent rule in a nonoverlapping starting quarter from onset -through the immutable horizon, or a possible automatic pre1956 alternate. +possible recent rule in a starting quarter from onset through the +immutable horizon, or a possible automatic pre1956 alternate. The recent scan uses the same annual assignment, fixed all-period use/disregard treatment, and special-window rules as the ordinary witness, relaxing only its fully insured prerequisite (404.130(a)–(d), (f)). If maximum feasible credits cannot satisfy any such recent rule and the alternate is unavailable, no -lower-credit filling can establish the period. Only ordinary insurance -without a flag fixes an overlapping first quarter for one filling and -treatment. A recent-only quarter does not establish when the flag begins. +lower-credit filling can establish the period. A recent-only quarter +does not establish when the flag begins. Blind fully-route declarations have no recent requirement and retain the same free flag-start fact. A complexity refusal during this scan preserves possibility so that the flag retains its own named refusal. @@ -270,10 +273,9 @@ possibility so that the flag retains its own named refusal. The horizon six-QC floor precedes the automatic alternate. The pre1956 alternate needs 20 QCs (RS .480 A) and an eligible start no later than December 31, 1955 (RS .480 B.1). Its -establishment witness uses one quarter satisfying that date limit, the -immutable horizon, and fixed prior-period nonoverlap together. A clear -post-1955 quarter cannot validate a different, overlapping alternate -start. This start check applies only to a declared established period; +establishment witness uses one quarter satisfying that date limit and the +immutable horizon together. This start check applies only to a declared +established period; the continuous clock still uses or disregards all prior periods and retains credited endpoints. The lower-credit 20/40 exclusion is unchanged. Its explicit flag adds no credit, condition, or route beyond the automatic @@ -288,10 +290,10 @@ Declared foreign credits receive `totalization_credits_unsupported`, with their evaluator row and weight, for zero, three, six, or ten own QCs once fixed chronology clears. The rule makes no claim about any totalization minimum, eligibility, foreign-credit count, or benefit. No totalization -source is used. A fixed overlap still makes establishment impossible, -because credits cannot move a candidate start or remove a supplied prior -quarter (I13). The validation-order fixture therefore retains foreign -credits but now proves fixed overlap, rather than a credit shortfall. +source is used. The round 11 validation-order fixture ends a prior +period in the onset quarter. Round 23 makes that declaration valid, since +a period may begin in the quarter a prior ended, so foreign credits and +every `CoverageCondition` keep their named refusals there. When prior periods are UNKNOWN, favorable disregard of every period can still decide the Boolean status even if the current period's derived @@ -438,11 +440,18 @@ A declaration of zero earnings or zero QCs must still declare provenance. All annual amounts are calendar-year covered amounts supplied by the caller. For an exit year they must already be limited to covered work through the exit month; the annual interface cannot reconstruct intra-year payment dates. -Subsequent years, and explicitly dated quarterly amounts or QCs after exit, -are input errors. Annual counts are capped by the number of assignable -quarters. No quarters after death, before birth, after exit, or not yet -begun at the query can be assigned. Disability interiors are excluded when -the prior periods are used (404.146; RS 00301.240). +Subsequent years, and explicitly dated quarterly amounts or QCs before +birth or after exit, are input errors. Annual counts are capped by the +number of assignable quarters. Section 404.146 bars a quarter that has not +begun, one after the quarter of death, one already counted, and a +disability-period interior, and RS 00301.230 B says "We can assign a QC +to any quarter in the calendar year" subject to those limits. An annual QC +therefore takes any begun quarter of its year through the death quarter: +neither a coverage exit nor a birth bars a quarter of its own year +(round 23). Wages paid after the death quarter still count toward the +year's total (Act 213(a)(2)(A)(ii), (B)(ii)); only the later quarters +cannot be QCs ((B)(i)). Disability interiors are excluded when the prior +periods are used (404.146(d); RS 00301.240). For example, a person born February 2, 1980 with four QCs in each year 2011–2020 and an exit in December 2020 is fully, currently, and disability @@ -465,11 +474,26 @@ Each `StatusDecision` supplies `insured`, `qc_count_lower`, `qc_count_upper`, It also reports the fully insured prerequisite separately through `fully_required`, `upper_fully_required`, `fully_qc_count_lower`, and `fully_qc_count_upper`, plus `qualifying_quarter` and -`upper_qualifying_quarter` for the first successful disabled quarter in -each earnings-bound world. Thus a disability witness can show 20 recent QCs -and still be uninsured because its duration-of-work requirement is not met. +`upper_qualifying_quarter`, the latest and earliest first successful +disabled quarter the record leaves open. Each is the first such quarter in +its earnings-bound world, except that where a listed prior binds, the pair +spans every basis that prior can rest on, and under UNKNOWN priors an +insured `upper_qualifying_quarter` is the onset quarter, which some prior +history can make the first (round 23). Thus a disability witness can show +20 recent QCs and still be uninsured because its duration-of-work +requirement is not met. The low and high witnesses each optimize assignment for that particular test. They need not have the same assignment or prior-period treatment. +FULLY's witness keeps whichever treatment gives the larger margin, so where +QCs sit inside a listed prior it can report the disregarded treatment's +count and requirement beside a `qcs_by_year` mapping and a +`fully_insured_requirement` that consider the period. For a woman born +1960-02-02 with a 1995 prior and four QCs in each of 1985 to 2000, a +January 2005 FULLY result reports 64 of 23, while its mapping sums to 62 +and the helper gives 22. 404.320(a) disregards a period only where +considering it would deny or reduce benefits; both treatments insure here, +so the status agrees, and the witness's count and requirement are a +diagnostic of the larger margin, not of that treatment (round 23). Where the first start can move, each keeps a filling with the reported start, and `qcs_by_year` and the top-level assignment describe the returned filling. The per-year QC mapping uses the disability-excluded context; the witness @@ -570,23 +594,23 @@ configuration receives `ongoing_disability_period_dli_horizon_unsupported`. | Agriculture | 1955–77 annual $100 increments, up to four, added to uncredited quarters. Covered 1951–54 agricultural wages must already be included in quarterly covered wages (RS .320/.325). | | Flexible assignment | Assign annual credits to whichever allowed quarters favor each test. Distinct tests expose distinct witnesses (404.143/.145; RS .230). | | Fully insured | One QC per elapsed year after 1950 or age 21 year, minimum six, maximum 40; stop before query, age 62, or death. Exclude only years partially or wholly in an established period; medical onset alone never caps elapsed years (214(a);404.110;RS .105). | -| Early male retirement cohorts | Before January 2, 1911 use age 65; January 2, 1911–January 1, 1913 use 1975, subject to earlier query/death (404.110; RS .105). | +| Early male retirement cohorts | Before January 2, 1911 use age 65; January 2, 1911–January 1, 1913 use 1975 (404.110(b)(2)(iii)–(iv); RS .105). Before 62 the query year ends a living man's count; from the year he reaches 62 it runs to that retirement year whatever the query, and a death year ends it if earlier (404.110(b)(3); round 23). | | Early male disability prerequisite | For every man born before January 2, 1913, the disability-specific fully insured elapsed-year endpoint is 1975 or the earlier relevant disability year (404.132(b)). It can differ from the retirement fully insured decision. | | Currently insured | Six QCs within 13 counted quarters ending with an actual declared death/RIB/DIB event, or the hypothetical query event. Every intersecting established period can extend the window, including the event's own period (214(b);404.120;RS .110). | | Disability | Scan onset through query for the first candidate quarter with the candidate-year fully insured prerequisite plus 20 QCs in 40 counted quarters, or a special rule (223(c)(1);216(i)(3);404.130-.132;RS .120/.130). | | Young worker | Before the age 31 attainment quarter: half the quarters after the age 21 quarter, dropping an odd remainder, minimum six. Fewer than 12 elapsed quarters uses 6/12; age 24 attainment quarter still uses 6/12 (404.130(c);RS .140). | -| Subsequent disability | With declared earlier special insured status, the special test can apply after 31, up to 20/40. Prior periods are all used or all disregarded, whichever admits insured status; endpoints count in windows only if QCs (404.130(f);RS .120/.147). | +| Subsequent disability | With declared earlier special insured status, the special test can apply after 31, up to 20/40. The rule records the same fact for a current period it begins: a nonblind holder's period that began before the age-31 quarter where 404.130(b) failed counts as such a prior for the quarters after it ends (404.130(d)(1); Act 223(c)(1)(B)(iii)). Where placement or an UNKNOWN year decides that basis, a date last insured the two bases put differently refuses by name (round 23). Prior periods are all used or all disregarded, whichever admits insured status; endpoints count in windows only if QCs (404.130(f);RS .120/.147). | | Blindness | Only the fully insured prerequisite, evaluated at each candidate disabled quarter; it can first qualify after medical onset, as can nonblind status (404.130(e),404.131;RS .150). | -| DLI | Latest fully-and-disability-insured quarter end, with explicit query censoring or frozen-exit horizon and FRA cap (RS .148). | +| DLI | Latest fully-and-disability-insured quarter end, with explicit query censoring or frozen-exit horizon and FRA cap (RS .148). With no established period, the DISABILITY decision itself scans quarters past FRA and only the date takes the cap, so a woman born 1950-02-02 with 40 QCs from 1975 to 1984, three in each of 2010 to 2014 and four in 2016 and 2017 is insured at 2017-01-01 in a January 2018 query, beside a date last insured of 1989-12-31 (round 23). | For prior disability periods, only years containing their endpoint quarters need assignment enumeration. Other annual credits maximize overlap directly. The calculation considers all-used and all-disregarded contexts, never a selectively chosen subset, including the alternate continuous-QC clock (RS .132 B.2, C.2). More than 4,096 boundary combinations receive an explicit -computational-coverage refusal only after every applicable fixed-overlap, -six-QC, and minimum-requirement impossibility proof. No approximate search -is used. +computational-coverage refusal only after every applicable six-QC and +minimum-requirement impossibility proof (round 23 removed the fixed-overlap +proof with the overlap check). No approximate search is used. For example, a man born February 2, 1900 queried in December 1974 with 20 QCs from 1969–1973 needs 14 QCs under the retirement fully insured rule, @@ -605,9 +629,9 @@ a subclass of the shared `FamilyConfigurationUnsupported`. The refusal order starts with full schema and history validation, including every raw row. The establishment possibility checks then precede coverage -refusals. Within those checks, fixed-quarter overlap comes first, followed -by declared foreign credits and any credit-route flag or raw-earnings flag -without a complete direct-QC envelope. The known-history nonblind +refusals. Within those checks, declared foreign credits come first, +followed by any credit-route flag or raw-earnings flag without a complete +direct-QC envelope. The known-history nonblind minimum-requirement proof follows before every boundary enumeration. A fully-route flag then preserves possibility immediately for blindness. Otherwise fewer than six maximum QCs feasible by the immutable start @@ -631,7 +655,20 @@ reachable refusals: `qc_amount_year_unsupported`, is tested with each unresolved row's feasible credit fillings. If the proof finds a possible filling or reaches an unresolved coverage limit, the first original conversion refusal in year order is raised unchanged. -Proved impossibility instead raises `InvalidFamilyInput`. With no deferred +These refusals are conservative: they don't ask whether the conversion +could change the answer, so 2028 wages of $1,969 refuse for a worker born +1990-06-15 with four QCs in each of 2010 to 2027, where an UNKNOWN 2028 +computes FULLY true at 72 of 16 (round 23). Each such row keeps its weight. +Proved impossibility instead raises `InvalidFamilyInput`, unless a listed +prior refuses first. A listed prior that no completion of the credits +supports shows the record omits credits or facts that could insure the +current period as well, so it refuses by its own name +(`disability_boundary_assignments_unsupported`, or +`disability_before_1956_unsupported` where RS .480 may have begun it), +after any deferred conversion refusal and before the input error. A +fully-route flag that can carry the prior suppresses that refusal. The +same check precedes the UNKNOWN-earnings refusal of an established period +whose validity rests on unknown credits (round 23). With no deferred reason, the existing specialist, date, applicability, and requested-status checks follow. In the requested-status checks, a positive ordinary DISABILITY witness does not bypass the observable alternate route when @@ -649,7 +686,7 @@ input. An input error propagates and creates no row. | Trigger | Reason code | | --- | --- | -| Unknown-year bounds decide a requested status differently | `unknown_earnings_years_decide_status` | +| Unknown-year bounds decide a requested status differently, an UNKNOWN year decides whether 404.130(b) began the current period where that moves the date last insured, or a flagged prior's first quarter has more than 4,096 completions | `unknown_earnings_years_decide_status` | | Unknown prior periods may change a requested status | `unknown_prior_disability_periods_decide_status` | | Unknown current establishment may change a requested status | `unknown_current_disability_period_decides_status` | | Any candidate end quarter for an UNKNOWN current ending changes a requested status | `ongoing_disability_period_end_decides_status` | @@ -669,9 +706,9 @@ input. An input error propagates and creates no row. | Separate pre1955 agricultural annual wages | `pre1955_agricultural_allocation_unsupported` | | Pre1951 self-employment income | `pre1951_self_employment_unsupported` | | Earnings require an increment after 2027 | `qc_amount_year_unsupported` | -| Query before 1968; blind query before 1973; subsequent-special query before May 1983 | `entitlement_before_1968_unsupported`, `blindness_before_1973_unsupported`, `subsequent_special_before_1983_unsupported` | +| Query before 1968; blind query before 1973; a query before May 1983 for the holder of a flagged prior whose age-31 quarter begins before then (round 23: 404.130(c) still covers an onset before 31) | `entitlement_before_1968_unsupported`, `blindness_before_1973_unsupported`, `subsequent_special_before_1983_unsupported` | | A subsequent-special period past 40 counted quarters where half the whole period and 20 of the last 40 give different results | `subsequent_special_long_period_unsupported` | -| More than 4,096 disability-boundary combinations, unresolved ordinary-establishment overlap requiring more than 4,096 credit fillings, a first start that placement or prior treatment can move with no one filling supporting the returned result, a lower date some ending can't reach on a filling with the reported start, a status or lower date some annual placement doesn't attain with no period in force under UNKNOWN priors or UNKNOWN establishment, or a listed prior that annual placement decides where an UNKNOWN year stands open or no filling that keeps the prior attains the result, after fixed overlap and every credit-count proof applicable to the surviving flag classes and foreign-credit declaration | `disability_boundary_assignments_unsupported` | +| More than 4,096 disability-boundary combinations, a first start that placement or prior treatment can move with no one filling supporting the returned result, a lower date some ending can't reach on a filling with the reported start, a status or lower date some annual placement doesn't attain with no period in force under UNKNOWN priors or UNKNOWN establishment, a listed prior that annual placement decides where an UNKNOWN year stands open or no filling that keeps the prior attains the result, a listed prior that no completion supports (before any input error the record would raise), or a date last insured that turns on whether annual placement let 404.130(b) begin the current period, after every credit-count proof applicable to the surviving flag classes and foreign-credit declaration | `disability_boundary_assignments_unsupported` | The round-3 observable-trigger audit covers every `CoverageCondition`. An explicit condition continues to refuse under its own reason when the @@ -690,7 +727,7 @@ unreachable 404.112 birth cohort does not invalidate an explicitly declared | `TRANSITIONAL_INSURED` | RS .101 B.1 lists "Transitional Insured Status" beside fully insured status for spouse benefits. It is absent from 404.130's four rules and supplies no recent QC. | Fully route | | `EARNED_BASIS` | RS .475 A says "fully insured status could be established by crediting certain wages on an earned rather than a paid basis". Its stated special method changes the fully insured prerequisite. | Fully route | | `SIMPLIFIED_PRE1951` | Act 213(c) says "For purposes of sections 414(a) and 415(d)"; 404.110(d)(1) says "For purposes of paragraph (b) of this section". Simplified credits affect fully insured status, not the independent recent test. | Fully route | -| `DISABILITY_BEFORE_1956` | RS .480 A requires "at least 20 quarters of coverage (QC) by the end of that quarter", the continuous-QC clock, and an eligible historical start; B.1 says "the last day on which it can begin is 12/31/55". For established periods that same start must clear prior-period overlap and the immutable horizon. The flag adds no credit or route beyond the automatic alternate check. A surviving declaration retains its named refusal. | Recent test | +| `DISABILITY_BEFORE_1956` | RS .480 A requires "at least 20 quarters of coverage (QC) by the end of that quarter", the continuous-QC clock, and an eligible historical start; B.1 says "the last day on which it can begin is 12/31/55". For established periods that same start must fit the immutable horizon. The flag adds no credit or route beyond the automatic alternate check. A surviving declaration retains its named refusal. | Recent test | | `RAILROAD_CREDITS` | RS .350 A says "we may use RR compensation in determining the number of quarters of coverage (QCs)"; RS .131 also identifies freeze credits. Compensation can add QCs before a final direct-QC declaration. | Raw earnings | | `FISCAL_TAXABLE_YEAR` | RS .220 says "we will allocate the SEI proportionately to the two calendars years"; 404.142 and .144 govern taxable-year allocation. The rule acts on earnings, not an already declared final QC count. | Raw earnings | | `SHORT_TAXABLE_YEAR` | RS .340 B.2.b says "credit SEI equally to the calendar quarter in which the TY ends" and preceding quarters in the taxable year; 404.142 and .144 govern allocation. | Raw earnings | @@ -728,7 +765,7 @@ allocation or adjudicate application facts. | Condition | Observable trigger or absent fact | | --- | --- | -| `SIMPLIFIED_PRE1951` | Raw 1937–1950 quarterly wages provide an aggregate divided by $400; post1950 upper QCs and the fully insured prerequisite bound whether it could decide status (213(c); 404.110(d); RS .315). UNKNOWN pre1951 years can supply unbounded raw wages and therefore also trigger the refusal. Direct `qc_quarters` declare credited quarters rather than raw wages. The simplified method does not apply to a disability claim. Filing, retroactivity, and section 227 facts remain unmodeled. | +| `SIMPLIFIED_PRE1951` | Raw 1937–1950 quarterly wages provide an aggregate divided by $400; post1950 upper QCs and the fully insured prerequisite bound whether it could decide status (213(c); 404.110(d); RS .315). UNKNOWN pre1951 years can supply unbounded raw wages and therefore also trigger the refusal. Direct `qc_quarters` declare credited quarters rather than raw wages and add nothing to the aggregate, so declaring pre-1951 years as flags waives this route: RS 00301.315 C.1's John Doe, born 1926-09-08, with 1949 declared as four QC flags, computes FULLY false at 27 of 37 in September 1991, while $5,700 of 1949 wages or an UNKNOWN 1949 refuses by this name (round 23). The simplified method does not apply to a disability claim. Filing, retroactivity, and section 227 facts remain unmodeled. | | `DISABILITY_BEFORE_1956` | The explicit flag adds no route beyond this automatic check. Medical onset and QCs reveal a possible RS .480 alternative: at least 20 total QCs and every counted quarter from 1951Q1 through the quarter before a qualifying 1952Q3–1955Q4 candidate quarter at or after onset, with at least six such quarters, under favorable all-period use or disregard (RS .132 B.2, C.2). For declared current establishment, that candidate must fit the immutable declared-end/continuity/death/FRA horizon. RS .480 A excludes the route when the lower-credit filling has 20/40 in the rule's disabled-quarter scan before October 1960; if only some fillings do, the alternate remains possible. Refuse automatically when this could change a failed disability predicate. Application conditions remain unmodeled. | | `DEEMED_FULLY_INSURED` | Wages and dates do not identify covered nonprofit employment or veteran status; retain the explicit flag (404.111–.112; RS .106/.107/.470). | | `TRANSITIONAL_INSURED` | Cohort dates alone do not identify the necessary historical benefit/application facts; retain the explicit flag (RS .101's transitional-benefit referrals). | @@ -805,24 +842,24 @@ to a statutory sentence that does not state it. | ID and input-error premise | Captured text and alternative-route defense | | --- | --- | | I1. A period cannot end before its onset or derived insured start; a supplied administrative end requires a declared established current period and closes a calendar month. | A216(i)(2)(C) says a period begins on the disability day or "the first day of the first quarter thereafter"; (D) says it ends "with the close" of the earlier listed month. C321(a), (c) agree. Every specialist route must still have a nonempty chronological period; no ordinary witness alone decides whether a specialist supplied the insured start. The end/established association is also a declaration contract. | -| I2. Birth, disability onset, death, prior periods, entitlement, and SSN assignment must have consistent lifetime ordering. A query or coverage end cannot precede birth; medical onset or supplied entitlement cannot follow the query month; onset cannot follow death. | B404.102 defines "You or your" as "the worker whose insured status is being considered"; A216(i)(2)(A) requires a period "during which an individual was under a disability". Dates refer to that same living worker. This lifetime and observation-calendar contract is independent of the insured route. It permits onset later within the query month and the quarter of death rather than imposing a day-of-query restriction. | -| I3. An established period must start before its FRA-ending boundary, including no start in the FRA month; all supplied prior periods are capped at the preceding month end. | A216(i)(2)(B): "no such period shall begin ... after such individual attains retirement age"; (D)(i) ends at "the month preceding the month" of FRA. C321(a), (c)(1) say the same. A start after the mandatory month-end is impossible under both clauses, including first-day birthdays. The cap supplies no evidence against an earlier UNKNOWN end. | -| I4. Supplied prior periods precede the current event/onset and query, do not overlap calendar quarters, and stay within the lifetime. | B404.130(f) refers to "a prior period of disability established for you". C321 gives chronological beginning and ending rules. Nonoverlapping quarter intervals are the declared history representation; specialist credits cannot change what "prior" or a unique represented quarter means. A known overlap is invalid, but overlap between a supplied prior period and a start derived in one UNKNOWN-earnings representative cannot disprove other fillings with a later nonoverlapping start. UNKNOWN history is not treated as supplied empty history. | +| I2. Birth, disability onset, death, prior periods, entitlement, and SSN assignment must have consistent lifetime ordering. A query or coverage end cannot precede birth; medical onset or supplied entitlement cannot follow the query month; onset cannot follow death. A DIB entitlement month must precede the FRA month, and an RIB entitlement month cannot precede the month of attaining 62 (round 23). | B404.102 defines "You or your" as "the worker whose insured status is being considered"; A216(i)(2)(A) requires a period "during which an individual was under a disability". Dates refer to that same living worker. This lifetime and observation-calendar contract is independent of the insured route. It permits onset later within the query month and the quarter of death rather than imposing a day-of-query restriction. The entitlement bounds are an interface premise: the benefit calendar comes from Act 223(a)(1) and 202(a)(2), which are not captured, and an event outside it contradicts the declaration rather than posing an insured-status question. | +| I3. An established period must start before its FRA-ending boundary, including no start in the FRA month. A declared current-period end after the preceding month end is an input error, as a continuity date after it already was (round 23); supplied prior periods are capped at that month end. | A216(i)(2)(B): "no such period shall begin ... after such individual attains retirement age"; (D)(i) ends at "the month preceding the month" of FRA. C321(a), (c)(1) say the same. A start after the mandatory month-end is impossible under both clauses, including first-day birthdays. The cap supplies no evidence against an earlier UNKNOWN end. No completion ends the current period later, so a later declared end is a contradiction, not a value to cap. | +| I4. Supplied prior periods precede the current onset and query, share no day with each other, and stay within the lifetime. A period may begin in the quarter the one before ended (round 23). | B404.130(f) refers to "a prior period of disability established for you". C321(a) says "Your period of disability begins on the day your disability begins if you are insured for disability on that day", and C321(b)–(c) end a period on a month's last day, so a new period can begin in the quarter the last one ended; RS .140 example 7 is that case. The shared quarter is an endpoint quarter of both periods, which B404.146(d)(1) and B404.130(f) count where it is a QC. Days, not quarters, are the declared history representation; specialist credits cannot change what "prior" means. UNKNOWN history is not treated as supplied empty history. | | I5. A supplied `special_insured` prior period begins before the age-31 attainment quarter. | B404.130(d)(1): a prior period "began before age 31" and the worker "were only insured under paragraph (c)"; (c)(1) requires age 31 not yet attained. A216(i)(3)(B)(iii) expressly uses "before the quarter" of age 31. The flag declares this particular adjudicated young-worker route, not every possible special credit regime. | | I6. An alien worker's actual pre2004 SSN assignment conflicts with declared SSPA applicability; birth on/after January 1, 2004 conflicts with declared exemption. Both never-assigned and an assigned SSN, or assignment before birth, remain invalid. A worker born before 2004 may pair a post2003 assignment or never-assigned status with an adjudicated exemption. | RS .102 B.1 says an alien assigned an SSN before 2004 "is exempt", including a nonwork SSN. B.3.b says, "If an alien worker could have legitimately been assigned an SSN before 1/1/2004, the worker is exempt from the requirements of section 211 of the SSPA." Its wrong-number SS-5 scenario issued another person's number "instead of assigning the alien worker their own SSN". Thus observed or convention-filled exemption overrides either later-assignment or never-assigned presumptions when legitimate pre2004 assignment was possible. Birth on/after January 1, 2004 rules out that exception independently of the assignment record. B.4.b's worker without an SSN "is nevertheless considered to meet the work SSN requirement" when work-authorized; meeting that requirement alone supplies no exemption. | -| I7. Explicit quarterly QCs or positive quarterly wages cannot occur before birth, after the query/coverage-end quarter, or after the death quarter. Every required coverage year is declared exactly once through the earliest query, exit, or death year. | A213(a)(2)(B)(i), (v): "no quarter after the quarter in which an individual dies" and "no quarter shall be counted ... prior to the beginning of such quarter"; B404.146(a)-(b) agree. Birth and supplied-record exit caps, complete years, and no implicit zeros are interface premises. Annual counts are capped rather than dated after exit. Specialist earned-basis or additional-credit declarations remain refusals and do not reinterpret an explicit ordinary covered-quarter declaration. | -| I8. A declared current establishment is invalid only after the shared possibility check excludes every route and every feasible prior/earnings filling. One ordinary filling must satisfy its insured start, recovery or administrative end, continuity, and overlap constraints together. | C320(b)(2) requires insured disability "in the calendar quarter in which you became disabled, or in a later calendar quarter"; C321(a) chooses the first such quarter. B404.130(a) supplies four ordinary rules and RS .480 supplies the alternate historical rule. The start horizon uses an inferred recovery month when I14 permits one, otherwise the declared end, together with continuity/query/death/FRA caps. Maximum credits establish only monotone insurance by that fixed horizon. A derived prior-quarter overlap requires a single lower-credit or enumerated filling whose first start also clears that overlap. A clear ordinary start found only through placement or treatment search establishes possibility and retains a named refusal; it does not select a status witness. An ordinary or alternate witness after the horizon cannot supply possibility. Foreign credits and the flag classes determine which credit-count proofs apply, in the refusal order above, before any alternate or boundary enumeration. The alternate's 20/40 exclusion instead uses U10's earliest date shared by every completion; a later witness cannot prove impossibility under every defensible reading of RS .480 A. | +| I7. Explicit quarterly QCs cannot occur before birth, after the query/coverage-end quarter, or after the death quarter; positive quarterly wages cannot occur before birth or after the query/coverage-end quarter. Every required coverage year is declared exactly once through the earliest query, exit, or death year. | A213(a)(2)(B)(i), (v): "no quarter after the quarter in which an individual dies" and "no quarter shall be counted ... prior to the beginning of such quarter"; B404.146(a)-(b) agree. Wages paid after the death quarter still count toward that year's total under A213(a)(2)(B)(ii), so they contradict nothing (round 23). Birth and supplied-record exit caps on dated rows, complete years, and no implicit zeros are interface premises. An annual count is undated, so neither cap bars a quarter of its year (round 23). Specialist earned-basis or additional-credit declarations remain refusals and do not reinterpret an explicit ordinary covered-quarter declaration. | +| I8. A declared current establishment is invalid only after the shared possibility check excludes every route and every feasible prior/earnings filling. One ordinary filling must satisfy its insured start, recovery or administrative end, and continuity constraints together. | C320(b)(2) requires insured disability "in the calendar quarter in which you became disabled, or in a later calendar quarter"; C321(a) chooses the first such quarter. B404.130(a) supplies four ordinary rules and RS .480 supplies the alternate historical rule. The start horizon uses an inferred recovery month when I14 permits one, otherwise the declared end, together with continuity/query/death/FRA caps. Maximum credits establish only monotone insurance by that fixed horizon; no derived start can overlap a prior (I4). A listed prior that no completion supports refuses by name before this input error (round 23). An ordinary start found only through placement or treatment search establishes possibility and retains a named refusal; it does not select a status witness. An ordinary or alternate witness after the horizon cannot supply possibility. Foreign credits and the flag classes determine which credit-count proofs apply, in the refusal order above, before any alternate or boundary enumeration. The alternate's 20/40 exclusion instead uses U10's earliest date shared by every completion; a later witness cannot prove impossibility under every defensible reading of RS .480 A. | | I9. Except for blindness with a fully-route flag, fewer than six maximum feasible QCs by the immutable start horizon proves current establishment impossible after foreign credits, credit-route flags, and unresolved raw-earnings flags have preserved their possible routes. | B404.110(b)(1): "You need at least 6 QCs but not more than 40 QCs"; B404.130(a): "you must be fully insured". The flag table supplies each exception's captured premise. A record composed entirely of direct final QC declarations (`qc_count` or `qc_quarters`) and UNKNOWN years fixes or bounds all admissible final credits from RR compensation and fiscal/short taxable-year allocation. This is the direct-credit input contract, not a claim that ordinary RSDI credits exhaust freeze-only military credits: B404.133 expressly supplies the latter, so `MILITARY_CREDITS` remains a separate credit route even with direct rows. Any raw row leaves the raw-earnings route unresolved. Period exclusions alone cannot add ordinary QCs. RS .480 A separately requires 20 QCs and the explicit `DISABILITY_BEFORE_1956` flag adds no route beyond the automatic alternate, so it cannot rescue a below-six declaration. Fully-route flags replace only the fully insured prerequisite; nonblind recent rules retain the universal horizon floor in I17, even under UNKNOWN prior history. Blindness with a fully-route flag bypasses that floor under 404.130(e). No ordinary floor applies to the unmodeled foreign-credit route (U11). | | I10. The supported calendar, mandatory historical sex, and explicit establishment declaration must be supplied: birth years 1870–9900, query years through 9990, sex for births before January 2, 1913, and establishment provenance whenever onset is present. | These are interface-domain requirements. B404.110(b)(2) and .132 apply different historical male/female endpoints; B404.110(c) excludes only a period "we established for you". Missing facts are not inferred. Calendar limits reserve space for date arithmetic and assert no legal incapacity outside the implementation domain; alternative credit routes cannot supply missing declared facts. | | I11. A continues-through observation requires established disability, cannot precede medical onset or the first feasible insured start, cannot exceed the pre-FRA or death boundary, and cannot follow a declared administrative end. | C320(b)(2) and C321(a) require the insured start; A216(i)(2)(D) and C321(c) bound the period's end. A declaration that a period was in force on a date requires that date to lie within one possible period. This is a dated observation, not an asserted ending; a date later than the query is allowed. Provenance and convention identifiers follow the existing fact schema. | | I12. A raw-credit conversion refusal cannot hide established-period impossibility that every feasible filling of that row preserves. | C320(b)(2), C321(a), and B404.110(b)(1) supply the insured-start and six-QC premises. The #530 input contract puts input errors before coverage refusals. Schema validation remains first; the four conversion refusals are deferred only for this proof, with unresolved rows bounded by feasible ordinary quarters. A surviving filling preserves the original refusal reason and note rather than manufacturing a supported status. | -| I13. If no starting quarter from onset through the immutable horizon clears all supplied prior-period quarters, current establishment is impossible independently of credit fillings, their count, or a specialist route. | C320(b)(2) and C321(a) require an insured beginning within that interval; I4's nonoverlapping-quarter representation applies to that same beginning. A credit route cannot move a candidate outside the fixed interval or remove a supplied prior quarter. This fixed contradiction is checked before specialist possibility and filling enumeration; it does not treat UNKNOWN prior history as supplied empty history. | +| I13. Round 23 retires this premise. Every supplied prior ends before onset and a period may begin in the quarter a prior ended (I4), so no starting quarter from onset through the horizon can overlap a supplied prior period. | C321(a) begins a period on its onset day when insured then, and RS .140 example 7 begins one in the quarter a prior ended. The round 6 records whose only start shared a prior's ending quarter now stand or fall on their credits. | | I14. A declared recovery-only historical end implies a recovery month two months earlier; recovery before the onset month or a derived start after that month is invalid. | C321(b) ends the period on "the last day of the second month following the month in which your disability ended". C320(b)(2) and B404.131(a) require an insured quarter in which the worker was disabled, so an administrative grace month cannot supply a new disabled quarter. The helper returns no recovery inference for an end on/after February 1, 1981, in/after the month preceding FRA, or in/after the death month. These carve-outs preserve the existing validity horizon and make no claim about paragraph (c) recovery or administrative ending rules. | | I15. With known prior history, no blindness, no foreign credits, no credit-route flag, and no raw-earnings flag outside a complete direct-QC envelope, fewer maximum feasible lifetime QCs than the lowest remaining recent-rule requirement proves establishment impossible before fully-route refusals or coverage enumeration. | B404.130(a) requires a recent rule "and you must be fully insured". The flag table's fully-route rules cannot change the independent recent-credit requirement. B404.130(b) needs 20 QCs; (c)–(d) permit the special half-elapsed-quarter rule with six-QC floor and 20-QC ceiling; RS .480 A also needs 20. At the earliest candidate start, remove every prior-period quarter from special elapsed time, including credited endpoints. Every actual use/disregard witness has at least those elapsed quarters, and later starts cannot reduce them. Taking the smallest applicable requirement therefore cannot exceed any true route minimum. Ignoring the fully insured prerequisite and window availability only relaxes the bound. Blindness (B404.130(e)) needs only fully insured status, and UNKNOWN prior history could remove further quarters; both disable this stronger numerical proof. Blindness removes I16's recent-credit requirement; UNKNOWN prior history skips its known-history scan, but does not disable I17's six-QC horizon floor. The minimum remains ahead of every boundary enumeration, including the recent scan. | -| I16. With known prior history and no route adding credits outside the declared envelope, a fully-route flag needs a possible clear first insured start or the automatic pre1956 alternate. Nonblindness retains the recent rule; blindness has none. | B404.130(a) requires one rule "and you must be fully insured"; (b) requires 20 QCs in 40 quarters; (c) and (d) supply the under31 and subsequent-special recent alternatives. C320(b)(2) permits the onset quarter or a later disabled quarter, and C321(a) selects the first qualifying quarter. The scan includes onset and horizon. For each complete annual placement and fixed prior treatment, only ordinary insurance without a flag fixes an overlapping first quarter. Recent-only insurance does not date the flag's fully insured status; the first flagged start may be later and clear. Blindness similarly leaves the flag's start unknown, including with zero QCs. Ordinary insurance in the overlapping quarter under every filling and treatment still proves impossibility. With UNKNOWN earnings, lower fillings are included; at most 4,096 placements/fillings are enumerated. When every candidate is already clear, the existing upper-credit scan suffices. It retains B404.130(f)'s favorable all-period use or disregard and annual assignment, and relaxes only the fully insured prerequisite. Upper credits bound the recent test when no start can overlap. In the overlap corner, complete placements and unresolved lower fillings are tested together, because removing or moving an early QC can delay the first insured start. An open RS .480 route remains an independent possibility for a fully-route flag. A complexity refusal is not impossibility and preserves the flag's own named refusal. The scan tests no flag-specific condition. | +| I16. With known prior history and no route adding credits outside the declared envelope, a fully-route flag needs a possible first insured start or the automatic pre1956 alternate. Nonblindness retains the recent rule; blindness has none. | B404.130(a) requires one rule "and you must be fully insured"; (b) requires 20 QCs in 40 quarters; (c) and (d) supply the under31 and subsequent-special recent alternatives. C320(b)(2) permits the onset quarter or a later disabled quarter, and C321(a) selects the first qualifying quarter. The scan includes onset and horizon. Recent-only insurance does not date the flag's fully insured status; the first flagged start may be later. Blindness similarly leaves the flag's start unknown, including with zero QCs. No start can overlap a prior (I4), so the upper-credit scan bounds every filling (round 23). It retains B404.130(f)'s favorable all-period use or disregard and annual assignment, and relaxes only the fully insured prerequisite. A fully-route flag that can carry a listed prior also suppresses that prior's unsupported-basis refusal (round 23). An open RS .480 route remains an independent possibility for a fully-route flag. A complexity refusal is not impossibility and preserves the flag's own named refusal. The scan tests no flag-specific condition. | | I17. Every declared-envelope nonblind establishment route has at least six QCs feasible by its immutable start horizon, including fully-route flags and UNKNOWN prior histories. Blindness without a fully-route flag retains the ordinary fully insured floor. | B404.130(b)(2) requires "at least 20 QCs"; (c)(3)(ii) and (d)(2)(ii) require "at least 6 QCs in the 12-quarter period". Paragraph (f) changes the counted window, never this floor. Only (e) removes the recent requirement, retaining fully insured status. RS .480 A also needs twenty QCs by its start. UNKNOWN prior history may remove elapsed quarters or open a subsequent-special route, but cannot remove this minimum. Credits after the horizon cannot satisfy it. Foreign and unmodeled credit routes remain outside the declared envelope and precede the proof. | -| I18. An established pre1956 alternate uses one start quarter satisfying prior-period nonoverlap, the immutable horizon and the historical date limit together. | C320(b)(2), C321(a), I13 and RS .480 B.1 require an eligible insured start no later than 12/31/55. A later nonoverlapping ordinary candidate cannot validate an overlapping alternate candidate. This check does not change the alternate continuous clock, credited endpoint treatment, lower-credit exclusion scan, or false/UNKNOWN establishment. Unlike a recent-only flagged candidate, an alternate candidate must itself satisfy every starting condition together; the flag-start correction does not move this candidate. | +| I18. An established pre1956 alternate uses one start quarter satisfying the immutable horizon and the historical date limit together. | C320(b)(2), C321(a) and RS .480 B.1 require an eligible insured start no later than 12/31/55. A later ordinary candidate cannot validate an alternate candidate that misses either limit. This check does not change the alternate continuous clock, credited endpoint treatment, lower-credit exclusion scan, or false/UNKNOWN establishment. Unlike a recent-only flagged candidate, an alternate candidate must itself satisfy every starting condition together; the flag-start correction does not move this candidate. | | ID and UNKNOWN collapse | Captured text and alternative-route defense | | --- | --- | @@ -830,18 +867,18 @@ to a statutory sentence that does not state it. | U2. UNKNOWN current establishment needs no new-period alternative if there is no medical onset or onset is at/after the statutory latest starting month. | A216(i)(2)(A)-(D) and C321 prohibit a period without disability or a nonempty pre-FRA interval. This removes an impossible new-period alternative only; it does not remove UNKNOWN prior history or an existing period's UNKNOWN administrative end. | | U3. With unknown prior/current periods, true ordinary FULLY and CURRENTLY status under favorable all-period disregard decides true. A DISABILITY witness must also survive any current-establishment completion that ends the disability before that witness. Every annual placement must attain the status at the quarter it reports with no period in force, because a period's own start can rule a filling out (round 19). | C320(a): "If benefits ... would be denied or reduced because of a period of disability, the period of disability will not be taken into consideration." B404.130(f) also permits counting all prior quarters if favorable. RS .120 requires all periods used or all disregarded; selective exclusions are not assumed. Specialist credit regimes are refused first. | | U4. With unknown periods, fewer than six maximum QCs feasible by the immutable horizon proves establishment impossible after routes adding undeclared credits are excluded, except for blindness with a fully-route flag; it supplies no foreign-credit impossibility proof. | B404.110(b)(1) and B404.130(a) supply the ordinary six-QC prerequisite. U3's disregard cannot manufacture credits. UNKNOWN prior history disables both I15 and I16; current nonblindness cannot exclude a past blind prior. The separate emptiness proof tests the earliest prior as blind, and proves emptiness only if no earlier quarter can supply fully insured status or the alternate. It can preserve a fully-route refusal with empty recent windows only after the universal six-QC horizon floor clears (I17). Foreign credits, credit-route flags, and raw-earnings flags outside a complete direct envelope also preserve named refusals. The direct-envelope contract and declared pre1956 alternate still obey I9; that alternate flag adds no route beyond B4. Blindness alone supplies no credits and does not replace the ordinary fully insured prerequisite. | -| U5. UNKNOWN earnings decide a requested Boolean only if all lower/upper ordinary earnings witnesses agree, under the permitted fixed-period/all-period treatments; an uncertain established start refuses only after at least one feasible filling survives. | B404.143 credits one QC for each increment, maximum four; B404.130 and .146 supply assignment/exclusion rules. Adding ordinary QCs cannot invalidate a fixed treatment. A derived start cannot be silently held fixed when the completion changes it. If a lower or upper representative cannot construct the declared period, but another single filling meets its end, continuity, and prior-overlap constraints, the public result is `unknown_earnings_years_decide_status`. If no ordinary filling can qualify by the declared end and all independent routes are impossible, it is an input error and creates no row. A deferred raw-conversion row uses temporary unknown fillings only for possibility, then retains its conversion refusal. Specialist possibilities and administrative-end candidates are considered separately. | +| U5. UNKNOWN earnings decide a requested Boolean only if all lower/upper ordinary earnings witnesses agree, under the permitted fixed-period/all-period treatments; an uncertain established start refuses only after at least one feasible filling survives. | B404.143 credits one QC for each increment, maximum four; B404.130 and .146 supply assignment/exclusion rules. Adding ordinary QCs cannot invalidate a fixed treatment. A derived start cannot be silently held fixed when the completion changes it. If a lower or upper representative cannot construct the declared period, but another single filling meets its end and continuity constraints, the public result is `unknown_earnings_years_decide_status`, unless a listed prior that no completion supports refuses first (round 23). If no ordinary filling can qualify by the declared end and all independent routes are impossible, it is an input error and creates no row. A deferred raw-conversion row uses temporary unknown fillings only for possibility, then retains its conversion refusal. Specialist possibilities and administrative-end candidates are considered separately. | | U6. UNKNOWN administrative end decides a status only when every end-quarter candidate from start through query/cap, plus permitted continuation, agrees, after applying any continuity lower bound. | A216(i)(2)(D) uses "whichever ... is the earlier"; C321(c)(3) includes "the last month for which you received benefits" after substantial gainful activity. Medical continuity cannot exclude early ends; a dated administrative continuity observation can. FRA/death caps limit the latest candidate and do not turn the unknown into a fact. Both ending and prior-history unknown facts remain disclosed when both are missing; UNKNOWN prior history uses the universal envelopes rather than inventing a derived current period to enumerate. The unchanged completion enumeration can include early endings rejected by I14 if declared concretely. Agreement across that larger set still implies agreement across every valid completion, while disagreement can preserve an extra refusal. An actual supplied end keeps its declared-date semantics; known ending provenance requires an ending date. | | U7. UNKNOWN SSPA applicability preserves an ordinary QC-only false status, but never a QC-only true status. | RS .102 B.2 says the worker "must meet one of the following additional requirements" and may fail "even if" the QC requirement is met. Applicability can remove ordinary insurance and cannot supply missing QCs. Known applicability retains adjudication refusal; any separate specialist path is refused first. | | U8. With UNKNOWN prior history, a known current period's start is certain onset only if the lower credits insure the onset on every annual placement with no period in force (round 19); otherwise the start stays unknown. | A216(i)(2)(C) and C321(a) make insured onset the earliest legal start. C320(a)'s disregard permits that witness, and no route can move this period before medical onset. Other potentially valid histories prevent an impossibility error but do not fabricate a start. | | U9. A continues-through observation removes only candidate administrative ends before its date; it never supplies an ending endpoint or removes UNKNOWN-end disclosure. | C321(c) enumerates actual ending events. Observation of a period still in force supplies a lower bound on those events, not their occurrence. Same-quarter ends remain possible, while a later-quarter observation makes the query quarter interior. | | U10. An automatic alternate-pre1956 possibility can be removed for every filling only when the lower-credit filling has ordinary 20/40 in a quarter disabled in every ending completion, before October 1960. | RS .480 A says "does not have 20/40 for freeze or DIB in any quarter before 10/60". Counts under a fixed all-period use/disregard treatment are monotone in added QCs. The scan retains query, 1960Q3, and month-before-FRA caps for every person (A216(i)(2)(D); C315(a); C321(a)–(b)). For established current periods, its shared date is the declared end minus two calendar months, or continuity date minus two when the end is UNKNOWN, or onset if neither is supplied; it is never before onset. The same two-month exclusion offset applies to FRA/death endings because an earlier recovery remains a possible completion, without inferring that it occurred. UNKNOWN establishment before FRA uses onset. A quarter counts only if its first month is on or before that shared date. RS .480 A's "any quarter" supports a wider scan, while "though under a disability" and "for freeze or DIB" support the shared disabled-quarter scan. A difference preserves the named refusal. Young-worker or blindness witnesses are not substituted for 20/40, upper-only witnesses cannot exclude every filling, and application facts remain unmodeled. | -| U11. Declared foreign totalization credits preserve an unmodeled establishment route immediately after fixed chronology, before every credit-count proof, and retain the named totalization refusal with their row and weight. | No captured rule establishes an own-QC floor for this unmodeled route. Ordinary B404.110(b)(1) cannot prove invalidity under every route. Zero, three, six, and ten own QCs therefore retain `totalization_credits_unsupported`; I13's fixed overlap remains invalid independently of credits. The rule makes no claim about any totalization minimum, eligibility, foreign-credit count, or benefit amount and uses no totalization source. | +| U11. Declared foreign totalization credits preserve an unmodeled establishment route immediately after fixed chronology, before every credit-count proof, and retain the named totalization refusal with their row and weight. | No captured rule establishes an own-QC floor for this unmodeled route. Ordinary B404.110(b)(1) cannot prove invalidity under every route. Zero, three, six, and ten own QCs therefore retain `totalization_credits_unsupported`. The rule makes no claim about any totalization minimum, eligibility, foreign-credit count, or benefit amount and uses no totalization source. | | ID and bound | Captured text and alternative-route defense | | --- | --- | -| B1. UNKNOWN annual ordinary QCs range from zero through four, reduced by assignable birth/query/death/exit quarters. Deferred raw-conversion rows use their feasible minimum/maximum fillings only for establishment possibility. Exact annual amounts are monotone in earnings; every calendar year stays in 0–4. | B404.143: "we cannot credit you with more than four QCs for any calendar year"; A213(a)(2)(B)(vi) prohibits duplicate calendar-quarter QCs; B404.146 excludes unbegun/death quarters. Birth/exit are supplied-record premises. Additional-credit regimes retain refusal and cannot escape this bound through an ordinary result. Deferred rows still raise their original conversion refusal after a valid possibility survives; no temporary filling is exposed as a computed status. | +| B1. UNKNOWN annual ordinary QCs range from zero through four, reduced to the year's quarters begun by the query and not after the death quarter; neither birth nor a coverage exit bars a quarter of its own year (round 23). Deferred raw-conversion rows use their feasible minimum/maximum fillings only for establishment possibility. Exact annual amounts are monotone in earnings; every calendar year stays in 0–4. | B404.143: "we cannot credit you with more than four QCs for any calendar year"; A213(a)(2)(B)(vi) prohibits duplicate calendar-quarter QCs; B404.146 excludes unbegun/death quarters, and RS .230 B lets a QC take "any quarter in the calendar year" subject to those limits. The exit bars only later years, which the history omits. Additional-credit regimes retain refusal and cannot escape this bound through an ordinary result. Deferred rows still raise their original conversion refusal after a valid possibility survives; no temporary filling is exposed as a computed status. | | B2. Ordinary fully insured requirements lie in 6–40 and exclude only established disability years. Every elapsed-year endpoint uses its relevant candidate year and the historical sex/cohort rule. | B404.110(b)(1), (b)(2), (c), .132; A214(a) says "not counting ... any year any part of which was included in a period of disability". Medical onset without establishment cannot freeze years. Deemed/transitional alternatives are refused before using the ordinary requirement as universal. | | B3. A simplified-pre1951 possibility uses the smallest known freeze requirement, or six for unresolved establishment/history, and maximum post1950 ordinary credits without exclusions. UNKNOWN pre1951 raw wages remain potentially decisive. DISABILITY compares the same bound at each quarter where the recent rule holds or blindness removes it. | A213(c) grants "one quarter of coverage for each $400" subject to resulting fully insured status; B404.110(c)-(d); RS .315 B.1-B.2 record alternate historical/application conditions. This is an over-approximation for refusal, not a computed deemed-credit answer. A favorable ordinary witness with a higher requirement cannot narrow it. | | B4. An alternate-pre1956 possibility uses maximum feasible QCs and an eligible 1952Q3–1955Q4 start with at least 20 total QCs and at least six continuous credited clock quarters, under favorable all-period use or disregard. It survives unless lower credits establish 20/40 in U10's shared disabled-quarter scan. | RS .480 A requires "at least 20 quarters of coverage" and "all quarters beginning with 03/51 ... are QCs", with "at least six"; B.1 permits the first freeze day 07/01/52 through 12/31/55. RS .132 B.2 applies prior-period exclusions to the continuous alternate clock, retaining credited beginning/ending quarters; C.2 requires all periods used or all disregarded. Candidate starts obey I8/I14's latest permissible horizon, so recovery before July 1952 cannot be rescued by the first alternate start. Exclusion instead obeys U10's earliest shared date, including the two-month offset for declared ends and continuity. A lower-credit ordinary 20/40 witness in that shared interval removes the route for all credit fillings; an upper-only or later witness preserves the named refusal. Unmodeled application conditions can remove candidates but do not prove an input error. An explicit `DISABILITY_BEFORE_1956` flag adds no route beyond this check. A fully-route flag may rely on this same alternate possibility when its ordinary recent rules fail; neither flag adjudicates the alternate's application conditions. | @@ -851,16 +888,16 @@ to a statutory sentence that does not state it. | B8. For a nonblind ordinary worker with no prior period, no DLI can lie more than 39 quarters after the last credited quarter. | B404.130(b)(2) requires "at least 20 QCs in the 40-quarter period ... ending with that quarter". After 39 later quarters no original QC remains. Blindness and prior-period special/exclusion routes disable this search shortcut; flagged or observable specialist routes refuse. | | B9. With unknown periods the disregard DLI is a lower bound and the permitted query/FRA/death horizon is the upper bound; unknown SSPA applicability reduces any positive DLI lower bound to `None`. | C320(a) permits favorable disregard; B404.130(f) permits counting all prior-period quarters; RS .102 B.2 imposes an additional requirement. The bound does not infer a particular recovery or history. Exemption can recover the ordinary upper witness but cannot exceed the calendar horizon. Round 19 requires every annual placement to reach the lower bound with no period in force, and refuses by name otherwise. | | B10. UNKNOWN-ending DLI bounds include every end candidate. With an unresolved ongoing end, known prior history, and frozen-exit future horizon beyond query, the named DLI-horizon refusal remains. | C321(c)'s alternative endings and RS .148's last qualifying quarter permit different historical DLI witnesses. The candidate extrema bound all declared endings; no recovery beyond the query is inferred. Refusal covers the unobserved future administrative fact. Round 17 requires every ending to reach the lower date on a filling with the reported start, and refuses by name otherwise. Under UNKNOWN priors every placement must reach it with no period in force, so no ending changes it (round 19). | -| B11. At most 4,096 combinations of disability endpoint assignments are searched exactly, after any applicable impossibility proof. | B404.143(b) and RS .230 permit favorable assignment; B404.130(f) makes credited endpoints decisive. Fixed-overlap, six-QC, and I15's minimum-requirement checks precede `_boundary_variants`, including both alternate-path calls and UNKNOWN-prior-history feasibility. A remaining excess returns `disability_boundary_assignments_unsupported`; computational complexity is neither a statutory impossibility bound nor permission to retain an all-invalid declaration. | +| B11. At most 4,096 combinations of disability endpoint assignments are searched exactly, after any applicable impossibility proof. | B404.143(b) and RS .230 permit favorable assignment; B404.130(f) makes credited endpoints decisive. Six-QC and I15's minimum-requirement checks precede `_boundary_variants`, including both alternate-path calls and UNKNOWN-prior-history feasibility. A remaining excess returns `disability_boundary_assignments_unsupported`; computational complexity is neither a statutory impossibility bound nor permission to retain an all-invalid declaration. | | B12. Ordinary counted windows have 13 quarters for current insurance and 40 for ordinary disability; young/subsequent special windows require half their elapsed quarters after dropping an odd remainder, with a six-QC minimum. The young-worker window holds at most 39 quarters. A subsequent-special period past 40 quarters computes only where the Act's whole period and 404.130(d)(2)'s 20 of 40 agree (round 17). | B404.120(a) says "13-quarter period"; .130(b) says "20 QCs in the 40-quarter period"; .130(c)-(d) and A216(i)(3)(B) supply the half-quarter, odd-remainder, and 6/12 alternatives. Blindness uses only the fully insured prerequisite. A fully-route flag must still leave a recent-rule witness or possible automatic pre1956 alternate where I16 applies; the pre1956 flag adds no route beyond that alternate. Specialist paths retaining possibility receive their named refusal. | | B13. Indexed annual QC amounts are at least the prior year's statutory increment and the rounded indexed 1978 amount, with nearest-$10 rounding and $5 ties upward. | A213(d)(2) chooses "the larger of" the prior increment and indexed amount, rounded to "the next higher multiple of $10" at a $5 tie. This exact parameter calculation has no disability or specialist alternative; input-domain checks require positive NAWI and a statutory prior increment. | | B14. Declaring continuity never widens the administrative-end candidate set; every returned status and count envelope remains valid for every retained concrete ending. | C321(c)'s ending events still govern. Set intersection with ends on/after the observation can only remove candidates; it creates neither an ending nor a new credit. The universal envelope remains unchanged where other unknown facts require it. | -| B15. Ordinary establishment overlap resolution enumerates at most 4,096 unknown-credit fillings after its fixed-date monotonicity, candidate-quarter, six-QC, and minimum-requirement proofs. | C320(b)(2) and C321(a) require one insured beginning consistent with the complete declaration. I13 settles fixed-quarter overlap and I15 settles a known-history nonblind lifetime-QC shortfall before enumeration. If neither settles the declaration, a search beyond the limit returns `disability_boundary_assignments_unsupported`; it asserts neither a concrete filling nor an input error. | -| B16. A deferred raw-conversion row retains independently computable ordinary credits in its minimum and every enumerated filling, and cannot exceed feasible calendar-quarter credits in its maximum. | A213(d)(2)'s prior-increment floor bounds future annual credits above by the captured 2027 increment applied to the supplied wages plus SE income; the possibility-only lower bound is zero. Raw 1937 allocation remains zero through four because A213(b)'s half-year rule is unresolved. For separate pre1955 agriculture or pre1951 SE, supported quarterly wage credits and supported post1950 calendar-year SE credits remain fixed; unresolved additional allocation can fill only remaining allowed quarters. Both minimum and maximum fillings may violate derived overlap even when a middle filling is valid, so neither endpoint alone proves impossibility. These bounds do not adjudicate a specialist allocation or replace its refusal. | +| B15. Round 23 retires the ordinary-establishment overlap search and its 4,096-filling limit: no derived start can overlap a prior (I4). | C320(b)(2) and C321(a) require one insured beginning consistent with the complete declaration, which maximum credits decide by the fixed horizon (I8). The remaining 4,096 limits are B11's and B17's searches and a flagged prior's first-quarter completions; each refuses by name and asserts neither a concrete filling nor an input error. | +| B16. A deferred raw-conversion row retains independently computable ordinary credits in its minimum, and cannot exceed feasible calendar-quarter credits in its maximum. | A213(d)(2)'s prior-increment floor bounds future annual credits above by the captured 2027 increment applied to the supplied wages plus SE income; the possibility-only lower bound is zero. Raw 1937 allocation remains zero through four because A213(b)'s half-year rule is unresolved. For separate pre1955 agriculture or pre1951 SE, supported quarterly wage credits and supported post1950 calendar-year SE credits remain fixed; unresolved additional allocation can fill only remaining allowed quarters. The maximum decides ordinary possibility, and the minimum the alternate's lower-credit exclusion (U10). These bounds do not adjudicate a specialist allocation or replace its refusal. | | B17. The first-start check refuses when flexible credits allow a better result at any possible start, and it searches at most 4,096 placements of the annual years that can change a first insured quarter. | 404.321(a) gives a record one start, and RS .230 makes placement flexible. A year wholly inside every tested window and untouched by a period adds its full count wherever its QCs fall, so it stays flexible. Without prior periods, an insured worst filling proves no filling starts later, and the check stops. The bound can refuse a declaration that no concrete filling improves, and a search can reach its limit before it attains a result. Round 16's longer search for each status's witness and round 17's lower-date search can reach the same limit. All return `disability_boundary_assignments_unsupported`, so the row keeps its weight; none asserts a filling or an input error. | -The round-5 adversarial audit revisits each row in both directions in -`scratch/review/round5-premise-audit.md`: a valid filling cannot be rejected, +The round-5 adversarial audit revisited each row in both directions: a +valid filling cannot be rejected, and a provably all-invalid declaration cannot become a denominator row. The fixed-end counterexamples correct I1/I8/U5 and the automatic historical cap in B4; the wrong-number SS-5 exception and its required possible pre2004 @@ -869,7 +906,8 @@ interface requirements, with no new statutory reading. Round 6 additionally checks both directions of refusal deferral (I12/B1), the alternate test's own 20/40 exclusion (U10/B4), and fixed-quarter overlap -impossibility before a filling limit can apply (I13/B15). Deferred refusals +impossibility before a filling limit can apply (I13/B15, both retired in +round 23). Deferred refusals cannot supply evaluator rows for all-invalid declarations, while a concrete valid filling retains the named refusal. The 20/40 exclusion must preserve valid current establishment and possible earliest prior @@ -882,8 +920,8 @@ completion, rather than only checking that rejection is sound. uses one or two UNKNOWN modern years (all five or 25 annual-count fillings), known counts zero through four, January/March/June/December ends, and blind/nonblind workers. -`test_overlap_declaration_exactly_matches_every_quarter_filling` uses -four missing-year shapes, prior endings in December 1971 or January 1972, +`test_shared_quarter_declaration_exactly_matches_every_quarter_filling` +(renamed in round 23) uses four missing-year shapes, prior endings in December 1971 or January 1972, current endings in April/December 1972 or January 1973, and every one of the 16 pre1978 quarterly masks. The specialist grids retain the automatic alternate-pre1956 route and every `CoverageCondition`. @@ -906,17 +944,13 @@ status/refusal; the UNKNOWN declaration must be invalid exactly when all concrete fillings are invalid. Every surviving UNKNOWN declaration is also evaluated to assert one retained row and its exact weight. -Two corners are excluded by name from this exactness claim. Arbitrary +One corner is excluded by name from this exactness claim. Arbitrary UNKNOWN prior history is not exhaustively enumerable in this bounded grid: its earliest-period possibility proof intentionally leaves unobserved administrative histories unresolved, while the explicit -short-DIB fillings test the retained existential witness. Large -ordinary-overlap searches remain excluded only when the fixed -candidate-quarter scan leaves a possible nonoverlapping starting quarter -and more than 4,096 credit fillings are still unresolved. They retain the -named computational refusal; that refusal asserts neither existence nor -impossibility. If every starting quarter overlaps a supplied prior period, -the declaration is invalid even above that filling limit. Specialist +short-DIB fillings test the retained existential witness. A second +corner, large ordinary-overlap searches, went with the overlap search in +round 23. Specialist administrative adjudication is outside the implemented ordinary surface; the specialist grid checks preservation of a possible route and its denominator, rather than claiming to adjudicate it. No bounded ordinary @@ -947,6 +981,11 @@ properties. The final execution report lists exact commands and results. `test_property_subsequent_special_and_dli_monotonic`. The separate intended query-fully/onset-disability distinction is pinned by `test_unknown_current_period_refuses_when_establishment_changes_full_status`. + One more QC can also bring a DLI earlier, as intended: it can let + 404.130(b) begin a current period that would otherwise rest on + 404.130(c) alone, and then 404.130(d) no longer reaches the quarters + after it (round 23): + `test_one_more_qc_can_bring_the_dli_earlier_intended`. - Unknown status, count, and DLI bounds contain every concrete filling or the rule refuses: `test_property_unknown_bounds_cover_every_filling`, `test_unknown_bounds_with_prior_disability_period`, and @@ -1004,13 +1043,13 @@ Round 4 extends those invariants across every statutory alternative: | An `InvalidFamilyInput` establishment conclusion excludes every enumerated ordinary, one-month/short-DIB-entitled, alternate-pre1956, and flagged-specialist filling; every valid refusal retains its evaluator row and weight. | `test_invalid_declaration_has_no_short_or_specialist_valid_filling` | | An alternate-pre1956 earliest prior period prevents UNKNOWN prior history from being proved empty, even when the later current onset itself is after 1955. | `test_unknown_prior_history_preserves_pre1956_alternate_prior_start` | | A valid UNKNOWN-earnings completion with its insured start on/before the declared period end prevents an input error, even if another representative starts after the end; uncertainty retains a refusal and denominator row. | `test_possible_unknown_earnings_filling_prevents_declared_end_input_error` | -| A valid lower-credit completion whose derived current start does not overlap a supplied prior period prevents an input error, even if the upper-credit representative overlaps its ending quarter; uncertainty retains a refusal and denominator row. | `test_possible_lower_earnings_filling_prevents_upper_overlap_input_error` | +| Every concrete filling of an UNKNOWN onset year starts a valid period, including a start in the quarter the prior ended (round 23); the UNKNOWN year moves the start and retains a refusal and denominator row. | `test_every_onset_year_filling_starts_a_valid_period` | Round 5 adds exact classification and administrative continuity: | Invariant | Hypothesis test | | --- | --- | -| Over the bounded modern and pre1978 overlap grids, `InvalidFamilyInput` occurs exactly when every concrete credit filling is invalid. A surviving filling prevents rejection, while an all-invalid declaration never acquires an evaluator row. | `test_unknown_declaration_exactly_matches_all_concrete_qc_fillings`, `test_overlap_declaration_exactly_matches_every_quarter_filling` | +| Over the bounded modern and pre1978 shared-quarter grids, `InvalidFamilyInput` occurs exactly when every concrete credit filling is invalid. A surviving filling prevents rejection, while an all-invalid declaration never acquires an evaluator row. | `test_unknown_declaration_exactly_matches_all_concrete_qc_fillings`, `test_shared_quarter_declaration_exactly_matches_every_quarter_filling` | | The automatically detected alternate-pre1956 start obeys the same fixed declared-end and continuity bounds as an ordinary start. A start horizon before July 1952 cannot use the first permitted July 1, 1952 freeze; a later permissible horizon preserves the specialist refusal. A recovery-only declared end must reach September to permit a July recovery month; a July continuity observation keeps the later UNKNOWN end possible. | `test_automatic_pre1956_start_respects_immutable_bound_property` | | An automatically detected historical start must fit before the actual month-before-FRA end, including when FRA and the first possible alternate start share July 1, 1952. | `test_automatic_pre1956_start_respects_fra_cap_property` | | An adjudicated section 211 exemption preserves the ordinary status/count result and one evaluator row for source-permitted post2003 and never-assigned facts; observed and convention-filled facts have equal statutory treatment. Pre2004-assigned aliens accept exactly the exempt declaration and reject declared applicability. An alien born on/after January 1, 2004 cannot supply the required possible pre2004 assignment and therefore cannot declare exemption. | `test_adjudicated_exemption_preserves_ordinary_count_and_evaluator_row`, `test_pre2004_assignment_accepts_exactly_the_exempt_applicability`, `test_wrong_number_exemption_requires_possible_pre2004_assignment` | @@ -1020,12 +1059,12 @@ Round 6 adds refusal ordering and settled route exclusions: | Invariant | Executing tests | | --- | --- | -| Adding any of the four early raw-conversion refusal facts where it cannot change an all-invalid declaration preserves `InvalidFamilyInput`, zero rows, and zero weight, independently of mapping order. Placing it where concrete credit fillings can validate the declaration preserves the original refusal reason and note. Multiple deferred reasons retain sorted-year priority, including when an overlap search reaches its coverage limit. | `test_irrelevant_early_refusal_fact_preserves_all_invalid_grid_case`; `test_every_early_qc_refusal_preserves_possible_declaration`; `test_deferred_refusals_keep_original_sorted_year_priority`; `test_unresolved_overlap_keeps_original_deferred_refusal` | +| Adding any of the four early raw-conversion refusal facts where it cannot change an all-invalid declaration preserves `InvalidFamilyInput`, zero rows, and zero weight, independently of mapping order. Placing it where concrete credit fillings can validate the declaration preserves the original refusal reason and note. Multiple deferred reasons retain sorted-year priority, including with many UNKNOWN years. | `test_irrelevant_early_refusal_fact_preserves_all_invalid_grid_case`; `test_every_early_qc_refusal_preserves_possible_declaration`; `test_deferred_refusals_keep_original_sorted_year_priority`; `test_many_unknown_years_keep_original_deferred_refusal` | | An unsupported future increment cannot hide a fixed earlier impossible end, for zero, one, or 10,000 raw wage dollars, including the age-62 and coverage-exit interfaces. The captured increment floor can prove too few possible credits; a sufficient possible filling keeps the original refusal. All schema/history errors still precede deferred refusals. | `test_unrelated_uncaptured_increment_cannot_hide_impossible_fixed_end`; `test_uncaptured_increment_bounds_preserve_both_classifications`; `test_schema_validation_precedes_deferred_qc_refusals` | | A lower-credit 20/40 witness in a quarter disabled in every ending completion, before October 1960, makes the automatic alternate unavailable under every added unknown-credit filling. The scan includes later disabled quarters and 1960Q3 only when shared by every completion, excludes 1960Q4 and quarters beginning in or after the FRA month for every person, and does not substitute blindness or the young-worker rule for 20/40. Round 10 corrects the shared date to the declared end minus two months or continuity minus two months, never before onset; without either date it is onset. An upper-only witness preserves the alternate refusal and evaluator row. | `test_fixed_twenty_of_forty_exclusion_survives_extra_unknown_credits`; `test_twenty_of_forty_before_october_1960_excludes_alternate_refusal`; `test_twenty_of_forty_scan_includes_later_disabled_quarters_before_1960`; `test_twenty_of_forty_alternate_exclusion_stops_before_october_1960`; `test_alternate_exclusion_uses_existing_disability_scan_fra_boundary`; `test_other_ordinary_disability_routes_do_not_supply_twenty_of_forty`; `test_some_twenty_of_forty_fillings_keep_named_alternate_refusal`; `test_independent_date_oracle_classifies_both_alternate_scan_directions` | | Excluding an unavailable alternate does not reject an ordinary current establishment or prove possible nonempty prior history empty. | `test_excluding_alternate_preserves_ordinary_current_establishment`; `test_excluding_alternate_preserves_possible_nonempty_prior_history` | -| If every possible starting quarter overlaps a supplied prior quarter, changing credit uncertainty cannot create a valid establishment or a refusal row, even above the filling limit. A neighboring nonoverlapping valid filling remains possible and retains the earnings refusal. | `test_immutable_overlap_is_independent_of_credit_uncertainty`; `test_fixed_same_quarter_overlap_precedes_large_filling_refusal`; `test_large_overlap_neighbour_keeps_valid_filling` | -| Deferred historical-credit fillings retain every independently guaranteed quarter. In the corrected continuous-clock case, every filling with Q1 uncredited survives, including all-zero through the alternate route; fixing an overlapping credited Q1 makes all eight admissible fillings invalid. Mapping order changes neither conclusion. | `test_deferred_quarter_fillings_keep_fixed_minimum_and_valid_middle` | +| A start may share the quarter a prior ended (round 23), so a record whose only possible start is that quarter stands or falls on its credits: UNKNOWN credits keep the earnings refusal and its row, every 1974–1977Q1 quarter credited starts the period on the onset day, and one fewer leaves no insured quarter. A prior ending in the onset quarter classifies like one ending the quarter before. | `test_a_shared_end_quarter_leaves_validity_to_unknown_credits`; `test_shared_end_quarter_validity_stays_with_unknown_credits`; `test_a_prior_ending_in_the_onset_quarter_classifies_like_one_before` | +| Deferred historical-credit fillings retain every independently guaranteed quarter. In the corrected continuous-clock case all 16 fillings keep a row with a named pre1956 refusal, since a credited Q1 starts the period on the onset day in the quarter the prior ended (round 23), and raw agricultural wages keep their deferred refusal with or without an independently credited Q1. Mapping order changes neither conclusion. | `test_deferred_quarter_fillings_survive_a_shared_onset_quarter` | Round 7 pins the eligibility boundary independently of the ordinary scan: @@ -1106,7 +1145,7 @@ denominators: | Invariant | Executing tests | | --- | --- | -| Adding foreign credits to a declaration clearing fixed chronology always preserves the totalization refusal, one row, and exact weight, independently of its own-QC count or flags. Fixed overlap still produces an input error and no row. | `test_foreign_credit_refusal_is_independent_of_own_qc_count` (Hypothesis); `test_foreign_credits_refuse_without_an_own_qc_floor`; `test_fixed_overlap_precedes_every_flag_and_foreign_route` | +| Adding foreign credits to a declaration clearing fixed chronology always preserves the totalization refusal, one row, and exact weight, independently of its own-QC count or flags. A prior ending in the onset quarter leaves a valid start, so every flag and foreign credits keep their named refusals there (round 23). | `test_foreign_credit_refusal_is_independent_of_own_qc_count` (Hypothesis); `test_foreign_credits_refuse_without_an_own_qc_floor`; `test_a_prior_ending_in_the_onset_quarter_leaves_a_valid_start`; `test_a_prior_ending_in_the_onset_quarter_keeps_every_route_refusal` | | With known prior history and no blindness, any flag set supplying no additional credit under the complete direct-envelope contract leaves a total-QC shortfall below the recent-rule minimum input-invalid. The expected minimum is computed independently of `_minimum_current_period_qcs`; round 12 supplements this numerical proof with the candidate-quarter scan below. | `test_no_credit_flag_set_cannot_hide_independently_proved_shortfall` (Hypothesis); `test_no_credit_flag_shortfall_and_exact_minimum_pair`; `test_review_recent_credit_shortfall_cannot_be_cured_by_deeming` | | A flag cannot turn a declaration meeting every ordinary requirement into an input error. At the exact ordinary or under31 minimum, each flag retains its own reason, one row, and exact weight. | `test_no_flag_rejects_declaration_meeting_every_requirement` (Hypothesis); `test_no_credit_flag_shortfall_and_exact_minimum_pair`; `test_credit_route_keeps_refusal_even_with_complete_direct_envelope` | | Fully-route flags retain their named refusals with blindness below six actual QCs, or with UNKNOWN prior history and at least six QCs feasible by the horizon, surviving the joint optimistic-clock proof. The declared pre1956 alternate cannot bypass the ordinary six-QC floor even with blindness, but at 20 QCs retains its refusal. | `test_fully_route_refuses_when_recent_credit_proof_does_not_apply`; `test_pre1956_flag_with_blindness_keeps_ordinary_six_qc_floor` | @@ -1120,8 +1159,9 @@ window. The unflagged declaration and each fully-route declaration now raise `InvalidFamilyInput`, with no evaluator row. Reducing the total to 19 remains invalid under the earlier numerical proof. The new recent scan keeps both inclusive quarter edges, the immutable horizon and recovery -bound, prior-period overlap, favorable assignment, all-period use or -disregard, and under31/subsequent-special alternatives. It ignores only +bound, favorable assignment, all-period use or disregard, and +under31/subsequent-special alternatives (round 23 removed its +prior-period overlap check). It ignores only the fully insured prerequisite. A recent witness preserves the flag's named refusal even when the ordinary fully insured requirement fails. Blindness, UNKNOWN prior history, an open automatic pre1956 alternate, or @@ -1138,7 +1178,7 @@ C321(a), and RS .480 A–B.1, not adjudications of the flags' own conditions. | A fully-route flag relaxes only the fully insured prerequisite. With the alternate absent, its establishment classification matches the independent recent oracle in both directions; a recent witness retains its named refusal even when the ordinary fully insured prerequisite fails. A possible alternate independently preserves that refusal. | `test_fully_flag_changes_fully_only_against_unflagged_recent_oracle` (Hypothesis); `test_fully_flag_exactness_includes_independent_alternate_oracle` (Hypothesis); `test_fully_route_relaxes_only_fully_insured_when_recent_rule_passes`; `test_fully_route_keeps_alternate_when_ordinary_recent_rule_is_closed` | | At every tested quarter, a true ordinary DISABILITY witness stays true when only the fully insured prerequisite is relaxed on identical credits. | `test_witness_keyword_only_relaxes_fully_prerequisite` (Hypothesis) | | The recent scan includes both the onset quarter and horizon quarter, and the horizon quarter counts even when the end falls inside it. It does not admit a witness beyond an inferred recovery bound. A credit one quarter too old cannot enter any candidate window. | `test_scan_includes_onset_and_the_earliest_quarter_of_forty`; `test_scan_includes_horizon_quarter_and_stops_at_recovery_bound`; `test_scan_reaches_last_candidate_quarter_even_with_end_inside_quarter` | -| The recent scan retains under-31 and subsequent-special requirements, favorable use of every prior period or disregard of every period, credited endpoints, and the shared rejection of candidate quarters inside supplied prior periods. | `test_special_recent_requirement_and_one_short`; `test_subsequent_special_recent_rule_can_pass_below_twenty_qcs`; `test_recent_window_uses_all_prior_periods_or_disregards_all`; `test_candidate_inside_prior_period_does_not_supply_recent_witness` | +| The recent scan retains under-31 and subsequent-special requirements, favorable use of every prior period or disregard of every period, credited endpoints, and an onset in the quarter a prior ended, which can supply the witness (round 23). | `test_special_recent_requirement_and_one_short`; `test_subsequent_special_recent_rule_can_pass_below_twenty_qcs`; `test_recent_window_uses_all_prior_periods_or_disregards_all`; `test_an_onset_in_a_prior_end_quarter_can_supply_the_recent_witness` | | Blindness and UNKNOWN prior history preserve fully-route refusals even with empty recent windows; UNKNOWN priors still require six horizon-feasible QCs and must survive the joint optimistic-clock proof. UNKNOWN recent years preserve possibility whenever an admissible filling supplies a recent witness, and every surviving concrete filling retains the flag's refusal. Complexity preserves that flag reason rather than substituting a computational refusal. | `test_empty_windows_keep_fully_route_blindness_and_unknown_prior_bypasses`; `test_unknown_recent_years_and_every_surviving_filling_keep_flag_reason`; `test_complexity_preserves_fully_route_reason` | | A declared pre1956 flag adds no establishment route beyond the automatic alternate: onset after 1955 with no ordinary route is invalid; either an ordinary witness or the historical alternate retains the named refusal. Credit-route and unbounded raw-earnings flags remain capable of adding credits, and a deferred conversion keeps its original reason when a recent witness remains possible. Surviving outcomes retain one evaluator row and exact weight 11/5. | `test_pre1956_flag_cannot_open_a_route_after_1955`; `test_pre1956_flag_keeps_named_refusal_when_alternate_conditions_hold`; `test_pre1956_flag_keeps_named_refusal_when_ordinary_route_is_open`; `test_credit_and_unbounded_raw_earnings_flags_can_add_recent_credits`; `test_deferred_conversion_keeps_original_refusal_with_possible_recent_rule` | @@ -1272,17 +1312,21 @@ With 1950 UNKNOWN and the extra four 1940 credits, enumeration finds one ordinary filling and fifteen alternate-refused fillings; the UNKNOWN declaration preserves `disability_before_1956_unsupported` and weight 11/5. -For the fixed-overlap example, birth February 2, 1940, onset February 15, -1977, a supplied January 1, 1970–January 31, 1977 prior period, and a March -31, 1977 current end leave only 1977Q1 as a current starting quarter. Four -QCs in each of 1968 and 1969, UNKNOWN 1974–1977, and zeros elsewhere cannot -clear that prior ending quarter. The January 1978 FULLY query raises -`InvalidFamilyInput` before the 8,192 combinations could trigger the -4,096-filling limit and create a row. -Moving only the prior ending to December 31, 1976 admits a valid filling: -all four quarters credited in each UNKNOWN year give an insured ordinary -current start on February 15, 1977. The UNKNOWN declaration therefore -retains `unknown_earnings_years_decide_status` (C320(b)(2); C321(a)). +Round 6's fixed-overlap example (birth February 2, 1940, onset February +15, 1977, a supplied January 1, 1970–January 31, 1977 prior period, four +QCs in each of 1968 and 1969, UNKNOWN 1974–1977, zeros elsewhere) no +longer turns on overlap. Its prior has no basis: she can reach 20 of 40 +at 1970Q1 only with QCs before 1968, which the record lacks, and past +blindness counts only from 1973. With an April 30, 1977 current end, +every filling of the UNKNOWN years refuses by the prior's name before any +input error (round 23). The round 6 tests now use a prior from January 1, +1973 and four QCs in each of 1966–1968. Those 12 QCs give fully insured +status for her 11 elapsed years, so the prior rests on past blindness, +and only 1977Q1, the quarter it ended in, can start the current period +before the February recovery. There 20 of 40 needs the prior disregarded +and every 1974–1977Q1 quarter credited, so the UNKNOWN years decide +validity and the record retains `unknown_earnings_years_decide_status` +(C320(b)(2); C321(a)). A deferred-allocation control has birth February 2, 1920, onset February 15, 1954, a July 15, 1952–January 31, 1954 prior period, current end @@ -1291,13 +1335,13 @@ Credits are one in 1938, four in each of 1946–1948, one in 1949, four in 1951, and two in 1952; other years are zero. The prior has RS .480's 20 lifetime and six continuous credits. Round 10 opens the alternate current route when prior -periods are used for the continuous clock. Of the 16 concrete 1954 masks, -all eight with Q1 uncredited are valid, including all-zero; all eight with -Q1 credited are invalid. The all-zero outcome is a named alternate refusal, -not an ordinary witness. Raw agricultural wages of $100 preserve -`pre1955_agricultural_allocation_unsupported`. Adding $50 of independently -credited Q1 nonagricultural wages -requires Q1 in every filling: all eight are invalid and create no row. +periods are used for the continuous clock. All 16 concrete 1954 masks are +valid: a credited Q1 starts the period on the onset day, in the quarter +the prior ended in January (round 23; round 6 rejected those eight). The +all-zero outcome is a named alternate refusal, not an ordinary witness. +Raw agricultural wages of $100 preserve +`pre1955_agricultural_allocation_unsupported`, with or without $50 of +independently credited Q1 nonagricultural wages. The fixed-end example has birth February 2, 2000, medical onset January 15, 2022, observed establishment, a January 31, 2022 declared end, four QCs @@ -1308,17 +1352,14 @@ UNKNOWN declaration raises `InvalidFamilyInput` through the evaluator; it cannot contribute a row of weight 3/2. The nine nearby combinations of two, three, or four 2021 QCs with January, February, or March 2022 ends fail for the same reason at an October 2022 query. The existing -round-4 lower-filling overlap and earlier-valid-end cases remain valid -UNKNOWN declarations and retain their original numeric assertions. -The overlap grid additionally minimizes an intended valid case: with the -January 1972 prior ending and December 1972 current ending, seven of the -16 UNKNOWN-1972 quarter masks are valid. They leave Q1 uncredited and -credit at least one later quarter, permitting a nonoverlapping insured -start before the fixed end. Both all-zero and all-four representatives -are invalid there, so checking only those representatives would reject a -valid declaration. Moving the declared end to March 1972 instead leaves -all 16 masks invalid; separate fillings cannot each supply half the -chronological constraints. +round-4 onset-year and earlier-valid-end cases remain valid UNKNOWN +declarations. In the shared-quarter grid, with the January 1972 prior +ending, a December 1972 current ending leaves 15 of the 16 UNKNOWN-1972 +quarter masks valid: any 1972 QC insures a quarter that begins by the +October recovery, and a 1972Q1 QC starts the period on the onset day in +the quarter the prior ended (round 23; round 5 found seven). An April +1972 ending puts recovery in February, so only the eight masks with a +1972Q1 QC are valid (round 5 found none). The automatic historical-bound counterexample has a woman born February 2, 1900, current onset January 15, 1952, observed establishment and empty @@ -1392,11 +1433,12 @@ July 15, 1952–January 31, 1972 prior period, current onset February 15, 1951Q1–1952Q2 QCs support the prior period under the alternate pre1956 route. Nineteen recent QCs in 1967–1971 and one in 1973, with UNKNOWN 1972 credits, give a valid January 1, 1973 current start when 1972 has -zero QCs. Positive 1972 fillings can instead derive a start in the prior -period's ending quarter and violate the quarter-overlap representation. -That invalid upper representative does not invalidate the UNKNOWN -declaration; `test_unknown_earnings_can_avoid_derived_prior_quarter_overlap` -and the lower-filling property retain the named earnings refusal and row. +zero QCs. Positive 1972 fillings instead start the period on the onset +day, in the quarter the prior ended, which round 23 accepts (RS .140 +example 7). The UNKNOWN year therefore moves the start: +`test_unknown_onset_year_earnings_decide_the_current_start` and +`test_every_onset_year_filling_starts_a_valid_period` retain the named +earnings refusal and row. The reviewer regressions additionally pin the 2026 blind-onset endpoint case (five continuing QCs versus six if the period ends in the event @@ -1484,12 +1526,18 @@ to 2000Q4–2003Q4 and yields six QCs, hence currently insured. RS .800's exhibit is a PDF and two GIF renderings of the same table. Its text was extracted from the PDF with pdftotext; the PDF and both GIFs are pinned by hash. The tests compare every one of its 38 rows: by birth cohort -(men before January 2, 1913 at age 65, women at 62), by footnote 1's -January 1 rule, and by year of death for a worker who attained 21 before -1951. They also compare every CFR 404.115 cohort row, including January -1/January 2 boundaries and sex distinctions. The PDF's footnote misprints -the male age-65 cohort as "born before 1/2/31"; its GIF rendering, its own -table and 20 CFR 404.132(b) say January 2, 1913, which the rule follows. +(men born before January 2, 1911 at age 65 and men born January 2, 1911 +through January 1, 1913 at 1975, under 404.110(b)(2)(iii)–(iv); women at +62), by footnote 1's January 1 rule, and by year of death for a worker who +attained 21 before 1951. They also compare every CFR 404.115 cohort row, +including January 1/January 2 boundaries and sex distinctions. Footnote 2 +says "The determining age for men born before 1/2/31 is age 65", which +404.110(b)(2)(iv) contradicts: age 65 applies only to a man who reached +62 before 1973. The exhibit's table merges men born 1910–1913 into one +1975 row, which 404.110(b)(2)(ii) through (iv) all give. The January 2, +1913 date in 20 CFR 404.132(b) belongs to the disability prerequisite's +1975 cap. The GIF renderings' text is not captured, so the rule claims no +reading of them. RS .149 links an uncaptured worksheet, which is not represented as read. RS .340 prints $10,900 in SEI but allocates $3,600 to each of three @@ -1534,8 +1582,9 @@ annual assignment. They change intermediate counts in RS .140 example 6 and RS .147 example 3, but neither example's insured conclusion. The short-tax-year $10,900 versus $10,800 reading remains a named public refusal; both readings give three QCs but differ by $100 in allocated -earnings. The exit-year annual-count cap remains an explicit interface -convention, not a statutory emigration exclusion. +earnings. An exit year's annual amounts cover work through the exit month, +an interface convention rather than a statutory emigration exclusion, and +since round 23 the exit bars no quarter of its own year. Medical onset versus administrative establishment and the event's own period are corrections required by 416(i)(2), 404.110(c), 404.120(b), and @@ -1582,8 +1631,9 @@ pre1956 test, and the wrong-number SS-5 exemption are captured source requirements. Dated observed continuity supplies a missing input; it is not a new statutory reading. They introduce no additional question for Max. Round 6's deferred raw-credit refusals implement the #530 input contract; -the alternate-route exclusion and fixed-quarter overlap apply captured -RS .480 A, C320(b)(2), and C321(a). Round 7 corrects the FRA bound using +the alternate-route exclusion and, until round 23, the fixed-quarter +overlap check apply captured RS .480 A, C320(b)(2), and C321(a). Round 7 +corrects the FRA bound using A216(i)(2)(D), C315(a), and C321(a)–(b). Its application to every person follows RS .480 A's “for freeze or DIB”; establishment is not a condition. The source conflict remains @@ -1642,7 +1692,7 @@ no payment adjudication and establish no dollar change. ## Source-conflict register Each `# Source conflict ` marker in `insured_status.py` and -`_insured_status_qc.py` names one of these ten readings on the marker's own +`_insured_status_qc.py` names one of these nine readings on the marker's own line. `tests/test_track_b_insured_status_readings.py` holds the markers and this list to the same ids. Each reading changes classification and row weight and computes no payment. @@ -1650,8 +1700,9 @@ and computes no payment. - `us:oasdi-insured-prior-disability-favorable-disregard` (`_witness`). RS 00301.140 example 9 prints that Sam isn't insured as of 5/93, and 404.130(f) counts a prior period's quarters where that favors the worker. - The rule tries counting every prior period and disregarding them all, and - keeps the favorable result. + The rule computes each status twice, once using every prior period, which + leaves its interior quarters out of the count, and once disregarding them + all, and keeps the favorable result. - `us:oasdi-insured-disability-period-endpoint-quarters` (`_allowed_quarters` in `_insured_status_qc.py`). 404.130(f) keeps a period's first and last quarters when each is a QC, and RS 00301.140 example 6 and RS 00301.147 @@ -1671,11 +1722,17 @@ and computes no payment. quarter, and refuses by name where the aggregate could decide a disability result. - `us:oasdi-insured-pre1956-alternate-any-quarter-scan` - (`_pre1956_alternate_possible`). RS 00301.480 A bars the pre-1956 alternate - for a worker with 20/40 "in any quarter before 10/60", and its other words - reach only quarters the period covers. The scan stops at the latest date - every completion's period covers, and a possible route refuses by name - (`disability_before_1956_unsupported`). + (`_pre1956_alternate_possible`, `_prior_basis`). RS 00301.480 A bars the + pre-1956 alternate for a worker with 20/40 "in any quarter before 10/60", + and its other words reach only quarters the period covers. The scan stops + at the latest date every completion's period covers, and a possible route + refuses by name (`disability_before_1956_unsupported`). A listed prior's + establishment shows its holder met the route's application conditions, so + B.1's counts on every completion, with 20/40 on none through September + 1960, hold such a prior. Where only one reading of A, or only some completion, + allows it, it refuses by the route's name; where every completion has + 20/40 in a quarter the prior covers, both readings exclude the route + (round 23). - `us:oasdi-insured-historical-end-recovery-month` (`_historical_recovery_month`). 404.321(b) ends a period on the last day of the second month after the month the disability ended, and the interface @@ -1689,12 +1746,6 @@ and computes no payment. proof that no UNKNOWN prior can insure the current period therefore lets the earliest prior rest on fully insured status, whatever `statutory_blindness` says. -- `us:oasdi-insured-flag-first-insured-quarter` (`_recent_rule_possible`). - 404.321(a) starts a period in the first quarter its holder is insured, and a - fully-route flag declares fully insured status but not when it began. Only - ordinary insurance ends the scan of a filling. A quarter inside a prior - period that meets only the recent rule leaves the start open, so a later - quarter can still make the flag's establishment possible. - `us:oasdi-insured-one-filling-first-start` (`_settle_first_start`, `_settle_listed_priors`, `_settle_lower_date`, `_settle_every_history`). RS 00301.230 makes annual placement flexible, and 404.321(a) gives a period one @@ -1712,7 +1763,16 @@ and computes no payment. quarters after age 21 with no cap, and 404.130(d)(2) caps the test at 20 of 40. `_witness` computes on the cap and refuses by name (`subsequent_special_long_period_unsupported`) where the uncapped count - would insure, and the possibility proof takes the Act's reading. + would insure, and the possibility proof takes the Act's reading. A third + parse asks for half the whole period's quarters, at most 20 QCs, anywhere + in the period, and the rule doesn't apply it. For a woman born 1960-02-02 + with a flagged prior from 1983-01-15 through 1983-06-30, QCs 1981:3, + 1982:3, four in each of 1984 to 1986, 1987:1 and 1993:1, and an onset + 1993-10-15, the Act asks 24 of the period's 48 counted quarters and finds + 20, the last 40 counted quarters hold 14 of 20, and only the third parse + insures; DISABILITY computes false at that onset, and an established + period raises `InvalidFamilyInput` (round 23). The refusal and this parse + stand until Max rules the pattern in d1920. ## Round 13 joint classification audit @@ -1742,8 +1802,10 @@ to current onsets from 1956; earlier UNKNOWN current onsets keep the existing conservative alternate/history machinery and are outside the added UNKNOWN-history oracle lattice. -For known priors, 404.321(a) fixes onset when insured then, otherwise the -first insured quarter. The rule does not know when a fully-route flag's +Round 23 retires the overlap cases in this paragraph and the next: a +period may begin in the quarter a prior ended, so no start overlaps a +prior. For known priors, 404.321(a) fixes onset when insured then, +otherwise the first insured quarter. The rule does not know when a fully-route flag's status began. An overlapping quarter fixes the first start only when the person is ordinarily insured there without any flag, for the same complete annual filling and all-period treatment. A recent-only witness cannot @@ -1771,9 +1833,9 @@ exclusion; no flag-specific substantive condition is adjudicated here. | --- | --- | | Nonblind declared-envelope routes need six credits by the immutable horizon, including UNKNOWN prior history and every fully route; later credits cannot repair a shortfall. | `test_unknown_prior_fully_route_floor_uses_horizon_credits`; `test_twenty_future_credits_cannot_repair_zero_by_start_horizon`; `test_classification_oracle_hypothesis`; `test_classification_oracle_unknown_years_straddle_start_horizon` | | Blind fully routes without prior overlap preserve their zero-credit named refusal; foreign and credit-adding routes precede the floor. | `test_blind_fully_route_with_zero_credits_keeps_named_refusal`; `test_foreign_and_credit_adding_routes_precede_floor`; `test_classification_oracle_modern_lattice` | -| One alternate start clears overlap, horizon and the 1955 limit together; credited endpoints and false/UNKNOWN establishment retain their treatment. | `test_review_alternate_start_must_clear_same_prior_overlap`; `test_alternate_uses_one_clear_candidate_after_prior_ending_quarter`; `test_unestablished_alternate_keeps_prior_treatment`; `test_classification_oracle_historical_boundary_lattice` | +| One alternate start fits the horizon and the 1955 limit together, and may share the quarter a prior ended (round 23); credited endpoints and false/UNKNOWN establishment retain their treatment. | `test_an_alternate_start_can_share_the_quarter_a_prior_ended`; `test_alternate_uses_one_clear_candidate_after_prior_ending_quarter`; `test_unestablished_alternate_keeps_prior_treatment`; `test_classification_oracle_historical_boundary_lattice` | | UNKNOWN priors cannot supply a special route without six credits before age 31, or couple incompatible earliest-prior and current windows. | `test_classification_oracle_unknown_prior_cannot_invent_special_eligibility`; `test_classification_oracle_unknown_prior_must_jointly_insure_current`; `test_classification_oracle_unknown_twenty_qcs_need_one_joint_start`; generated `test_classification_oracle_hypothesis` | -| Each known-prior filling and treatment has one first insured start. Only ordinary insurance without a flag fixes an overlapping quarter. A clear start requiring a different placement or treatment keeps a named refusal, rather than settling statuses by iteration order. | `test_classification_oracle_fully_flag_cannot_delay_an_insured_onset`; `test_classification_oracle_blind_fully_flag_still_has_one_first_start`; `test_classification_oracle_annual_placement_can_delay_first_insured_quarter`; `test_classification_oracle_annual_placement_boundary_lattice`; `test_disability_witness_uses_the_legal_annual_start_filling` | +| Each known-prior filling and treatment has one first insured start. A start requiring a different placement or treatment keeps a named refusal, rather than settling statuses by iteration order, and a fully-route flag keeps an insured onset (round 23 renamed these tests). | `test_classification_oracle_fully_flag_keeps_an_insured_onset`; `test_classification_oracle_blind_fully_flag_still_has_one_first_start`; `test_classification_oracle_annual_placement_can_delay_first_insured_quarter`; `test_classification_oracle_annual_placement_boundary_lattice`; `test_disability_witness_counts_the_quarter_a_prior_ended` | | Invalid declarations have zero rows and weight; each valid computed or named-refusal outcome has exactly one row and its full rational weight. | Every new regression and lattice evaluation; `test_classification_oracle_hypothesis` | ### Independent oracle and bounds @@ -1893,8 +1955,9 @@ independent status oracle: adding a fully-route flag preserves every row; reversing annual-placement and prior-treatment iteration preserves public results; admitting past blindness preserves UNKNOWN-history rows; every computed status equals the most favorable lawful filling in the oracle's -bounded space. Existing impossible-overlap, six-QC, horizon, recovery, -continuous-clock, and FRA invariants remain in force. +bounded space. Existing six-QC, horizon, recovery, continuous-clock, and +FRA invariants remain in force; round 23 retired the impossible-overlap +one. ### Premise attacks and source readings @@ -1928,8 +1991,7 @@ period ends and a claiming-age query. At most 576 placements, two establishment treatments and two status treatments are considered per declaration. The 36 deterministic lattice cases, the reviewer case, and 24 generated examples plus the explicit reviewer example cover women born 1960-02-02. The executable module header -gives the remaining finite bounds; run times and every observed -disagreement are recorded in `scratch/review/fix-round-14-report.md`. +gives the remaining finite bounds. DLI, raw earnings, UNKNOWN earnings/ends, foreign routes, and specialist flags are outside this oracle's claim. @@ -1950,7 +2012,9 @@ is one of those requirements. RS 00301.315 B.1 alone says, "The simplified method does not apply to disability claims." The statute and the regulation therefore reach the disability prerequisite (P1, P2). Filing facts stay unmodeled, so the rule credits no deemed quarter. It refuses by name where -the aggregate could decide an answer, and it never rejects such a +an aggregate of declared raw wages or of an UNKNOWN year could decide an +answer (pre-1951 years declared as QC flags add nothing to it; round 23), +and it never rejects such a declaration or answers it false. A row that a defensible reading keeps stays a row. Source conflict `us:oasdi-insured-simplified-pre1951-disability-scope`. @@ -2239,10 +2303,13 @@ shows SSA applying the cap. Past 40 counted quarters the sources give two readings: - half the whole period, as the Act says; -- 20 of the last 40 counted quarters, as 404.130(d)(2) says. Those are the - quarters of 404.130(b), so this reading adds nothing to that rule. +- 20 of the 40 counted quarters ending with the tested one. 404.130(d)(2) + says "out of 40 calendar quarters" without saying which; every period in + 404.130 ends with the tested quarter, and those are the quarters of + 404.130(b), so this reading adds nothing to that rule. -A third parse takes 20 QCs anywhere in the period. The session rejected it. It +A third parse takes 20 QCs anywhere in the period. The session rejected it +on arguable grounds, and round 23 lists it in the register for Max. It drops "out of 40 calendar quarters", the denominator 404.130(d)(2) states, and every period in 404.130 ends with the tested quarter, so the test would stop asking about recent work. RS 00301.147 doesn't decide this parse. It prints @@ -2265,10 +2332,10 @@ for an age-62 FULLY request. The rule now computes only where the two readings agree. `_witness` refuses with `subsequent_special_long_period_unsupported` when no candidate insures and the whole period holds at least half its quarters after dropping an odd -remainder. The refusal needs no fully insured test: across 166,080 combinations -of birth, prior and query date, half a long period exceeded the requirement by -at least 10 QCs, and `test_half_a_long_period_clears_the_fully_insured_count` -holds that. At 40 counted quarters or fewer the readings match. A FULLY +remainder. The refusal needs no fully insured test: half a long period's +counted quarters is at least the 404.132 requirement over births, priors and +query dates, which `test_half_a_long_period_clears_the_fully_insured_count` +holds. At 40 counted quarters or fewer the readings match. A FULLY request with no established period reads no disability test, so it still computes. The refusal reaches a date last insured that the 40-quarter rule ends before the Act's reading would, because the date scan calls the same @@ -2631,7 +2698,7 @@ with more than 96 placements. All 2,450 checks held: 1,034 computed, 1,164 refused by name and 252 raised `InvalidFamilyInput`. The first pass of this round's 40 listed mutations -(`scratch/review/round19_mutate.py`) ran through the insured status modules with +(`round_19_mutations` in `track_b_insured_status_mutations.json`) ran through the insured status modules with no restricted open, and 38 failed a named test. `start_search_skips_prior_years` and `date_search_drops_binding` survived, and `test_a_prior_reaches_a_year_the_start_cannot` and @@ -2923,7 +2990,8 @@ The wide search drew 150 fresh seeds for each of eight checks on 1,276 checks held: 884 computed, 286 refused by name and 106 raised `InvalidFamilyInput`. -The list of mutations (`scratch/review/round21_mutate.py`) re-derives round 20's +The list of mutations (`round_21_mutations` in +`track_b_insured_status_mutations.json`) re-derives round 20's 41 at this round's source, less `unflagged_refuses_unsupported_prior`, whose branch the rule no longer has, and adds 17 of this round's own. A first pass of all 57 through rounds 19 to 21 ran with no restricted open, and 54 failed a named @@ -3011,7 +3079,7 @@ The review's record is round 21's for a woman born 1968-02-02, without the 1980 to 1984 QCs: four QCs in each of 1989 to 1992, three in 1993, one in 1998, four in each of 1999 to 2002 and three in 2003, with a listed prior from 1998-01-01 through 1999-12-31, before the 1999Q1 quarter she attains 31. The 36 quarters -from 1989Q2 through 1997Q4 hold 18 QCs, half of them, so 404.130(c) holds the +from 1989Q2 through 1998Q1 hold 18 QCs, half of them, so 404.130(c) holds the prior on every placement. 404.130(b) finds 19 of 40 there and needs the 1998 QC in 1998Q1. On that placement the date falls on 2007-12-31, and on past blindness on 2008-03-31. `f37f7f79` reported 2008-03-31 for a January 2008 @@ -3098,7 +3166,8 @@ flagged prior begin in 1991Q1, the quarter she attains 31, which the interface rejects, and CI drew that case at `f37f7f79`. The test now draws flagged starts through 1990Q4, and its oracle holds an unflagged prior to 404.130(b). -The list of mutations (`scratch/review/round22_mutate.py`) takes round 21's 62 +The list of mutations (`round_22_mutations` in +`track_b_insured_status_mutations.json`) takes round 21's 62 at this round's source and re-derives `ordinary_keeps_special_route`, which drops `not ordinary_only`, against the new condition. It adds eight of this round's own, for 70. `unflagged_reads_paragraph_c` in `_witness`, and @@ -3154,6 +3223,406 @@ These tests execute the invariants this round adds: `test_that_refusal_keeps_the_row`); - the current period keeps 404.130(c) (`test_status_stress_under_31`). +## Round 23 a period keeps the basis it began on + +Verification class: statutory conformance on invented declarations only. This +correction admits no population, behavioral, payment, or forecast claim. An +independent review of `7b5b126a` reported seven mediums, 17 lows and six nits +(PR #562 comment 6596920658). The rows and passages above now state the rule as +it stands, and this section records what changed and why. + +### A current period begun on 404.130(c) alone + +404.130(d)(1) reaches someone "disabled again at age 31 or later after having +had a prior period of disability established which began before age 31 and for +which you were only insured under paragraph (c)", and Act 223(c)(1)(B)(iii) +says the same. A listed prior carries that fact as `special_insured`, but +`7b5b126a` appended the current period it began without it, so the quarters +after that period lost 404.130(d). The review's record is a woman born +1980-02-02 with an onset on 2003-01-15 and a period that ends 2004-12-31, two +QCs in 2001, four in 2002, four in each of 2009 to 2011 and one in 2012, +queried in January 2013. At 2003Q1 the 12 quarters from 2000Q2 hold the six QCs +of 2001 and 2002, so 404.130(c) holds, and 404.130(b) finds six of 40. At +2012Q4, past the 2011Q1 quarter she attains 31, 404.130(d) counts the 47 +quarters from 2001Q2 less the period's eight, an odd 39 it reduces to 38, and +the 19 QCs meet half. `7b5b126a` reported 2006-06-30 as an exact date last +insured, and the rule now reports 2012-12-31 +(`test_a_period_begun_on_paragraph_c_alone_opens_paragraph_d_after_it`). A +frozen exit keeps that date, a second record holds through its 2016Q1 query +quarter (`test_the_flag_reaches_a_frozen_exit_and_a_later_record`), and an +UNKNOWN end gives the range from 2004-12-31 to 2013-03-31 +(`test_an_unknown_end_spans_the_flagged_period_lengths`). + +`_current_period_special` now records that fact for a period the rule begins: +the period began before the quarter its holder attains 31, its holder wasn't +blind, and 404.130(b) failed in its first quarter. `_complete_current_period` +writes the flag on the period it appends, and `_current_period_completions` +keeps it on each ending. Where annual placement decides whether 404.130(b) held +in that quarter, the function returns None, and with listed priors it stays +open whenever some placement meets 404.130(b). `_settle_current_basis` then +computes the date on both bases and refuses by name where they differ, with +ASSIGNMENT_COMPLEXITY where placement decides and UNKNOWN_EARNINGS where an +UNKNOWN year does. With one 1997 QC and four in each of 1998 to 2000 added, +404.130(b) finds 19 of 40 at 2003Q1. A 1993 QC counts there only in 1993Q2 to +Q4, and no later window counts it, so its placement decides between the two +dates, as an UNKNOWN 1997 does +(`test_a_placement_or_year_that_decides_the_basis_refuses`). The flag adds +404.130(d) only for quarters after the period, so only the date last insured +can move, and FULLY computes on either basis. + +One more QC can bring the date earlier, as the law reads. With 19 QCs before +the onset, 404.130(b) fails at 2003Q1, the period rests on 404.130(c) alone, +and 404.130(d) holds through 2012Q4. A second 1997 QC makes 20 of 40 at 2003Q1, +so 404.130(b) began the period, 404.130(d) never applies, and 20 of 40 last +holds at 2012Q3 (`test_one_more_qc_can_bring_the_dli_earlier_intended`). The +test labels this violation of QC monotonicity intended. + +`test_an_ended_current_period_counts_as_the_prior_it_becomes` lists the period +the rule begins as a prior, with the flag 404.130(b) implies, and checks that +both give the same date. Its records put every 1997 to 2002 QC in the 40 +quarters ending 2003Q1, so 404.130(b) holds there on every placement or on +none. A run over its whole strategy space, 11,700 records, computed 11,599 that +agree and refused the other 101 by the long-period register entry's name. + +### A period that shares the quarter a prior ended in + +404.321(a) begins a period on the onset day if its holder had insured status +then. In RS 00301.140's example 7, Jane's prior period ended on October 31, +1990, and she became disabled again on December 3, 1990, in the same quarter. +`7b5b126a` required each period to begin in a quarter after the one before it +ended, so her established record raised `InvalidFamilyInput` and lost its row, +and I13 called the case impossible. Periods may now share a quarter but not a +day (I4). Jane's period begins on 1990-12-03 +(`test_rs00301_140_example_7_begins_on_the_onset_day`, +`test_any_onset_after_the_prior_day_keeps_its_own_start`), and a day two +periods both cover stays an input error +(`test_periods_still_may_not_share_a_day`). No candidate start can overlap a +prior now, so round 23 removes the overlap search, its 4,096-filling limit and +the fixed-overlap proof, and retires I13 and B15. 404.321(b) and (c) end a +period on a month's last day, so under UNKNOWN priors a prior can end in the +onset quarter only before a February or March onset +(`test_unknown_priors_may_end_before_a_later_onset_in_its_quarter`). + +The register entry `us:oasdi-insured-flag-first-insured-quarter` read a +recent-rule quarter inside a prior period, where no start could fall, as +leaving a flag's start open. A start may now fall in any quarter from the +onset, so round 23 drops the entry and its marker in `_recent_rule_possible`, +and the register holds nine readings. + +### A coverage exit bars only later years + +RS 00301.230 B lets an annual QC go to "any quarter in the calendar year", +subject to RS 00301.240, which bars a quarter not yet begun, one after death +and a disability period's interior (404.146). `7b5b126a` also barred an exit +year's quarters after the exit quarter, and a birth year's quarters before the +birth quarter, and the law has neither bar. With a February 2020 exit, $6,000 +of 2020 wages give four QCs, but `7b5b126a` left them one quarter, and FULLY +failed at 3 of 6, where the law gives 6 of 6 +(`test_an_exit_year_credits_any_begun_quarter`). An exit now bars only the +years after it, which the history leaves out, and a quarterly QC or earnings a +caller declares after the exit quarter stays an input error +(`test_quarterly_bounds_name_themselves`). Every exit month of a year gives the +December exit's result (`test_the_exit_month_moves_nothing_in_its_year`), 40 +QCs need no later quarter (`test_forty_qcs_need_no_later_quarter`), an UNKNOWN +exit year refuses whatever its exit month +(`test_an_unknown_exit_year_refuses_whatever_its_exit_month`), and an +established period keeps its row after a February exit +(`test_an_established_period_keeps_its_row_after_a_february_exit`). Dropping +the birth bar answers low 13: $3,120 of wages in the year of a December 2000 +birth gives four QCs (`test_a_birth_year_credits_quarters_before_the_birth`). + +### The first insured quarter on every basis + +DISABILITY reports its first insured quarter (404.131(a), 404.321(a)). Where a +listed prior binds the placement, `7b5b126a` took that quarter from whichever +kept filling first tied on count. For a woman born 1959-02-28 with a prior from +2000-04-01 to 2005-03-31 and an onset on 2007-01-01, it reported 2010-07-01, +though the filling that begins the prior on 404.130(b) at 2000Q2 holds 20 of 40 +at 2007Q1 (`test_a_binding_prior_keeps_the_earliest_qualifying_quarter`). +`_witness_rank` now ranks an earlier insured quarter above a larger count for +DISABILITY. + +Where a binding prior's two bases, 404.130(b) and past blindness, give +different witnesses, each status now reports the range they give, and the +result lists `prior_disability_period_basis` among its unknown facts. Take +round 22's record with two QCs in 2003 rather than three, two in 2008 and an +onset on 2008-01-01. On 404.130(b) the 1998 QC sits in 1998Q1, and 2008Q2 first +holds 20 of 40; on past blindness it may sit later, and 2008Q1 holds 20. The +result reports 2008-04-01 with an upper qualifying quarter of 2008-01-01 +(`test_a_prior_basis_split_widens_the_qualifying_quarters`), and a 1955 birth +widens the count to 20 to 21 the same way +(`test_a_prior_basis_split_widens_the_count`). Established, the split moves the +period's start, and the refusal now names the listed prior rather than +placement in general (`test_a_split_start_names_the_listed_prior`, nit 29). + +Under UNKNOWN priors, `7b5b126a` reported DISABILITY's qualifying quarter as +exact bounds from the world with no prior. An UNKNOWN prior can set quarters +aside and reach earlier QCs (404.130(f)), so the first insured quarter can fall +as early as the onset quarter (404.131(a)). For a woman born 1961-02-02 with an +onset on 2007-01-01, no prior gives 2007-04-01, and a prior from 1990 through +1999 that begins on 404.130(b) gives 2007-01-01. The result now reports +2007-04-01 with an upper qualifying quarter of 2007-01-01 +(`test_unknown_priors_reach_the_onset_quarter`). + +### A man's elapsed years + +404.110(b)(2)(iv) ends a man's count at "the year you became age 65" if he +became 62 before 1973, and (iii) ends it at 1975 if he became 62 in 1973 or +1974. `7b5b126a` ended a living man's count at the query year, so a man born +1908-07-01 with 20 QCs from 1951 to 1970 was fully insured in December 1971 at +20 of 20. His count runs from 1951 through 1972, so he needs 22 +(`test_a_man_who_reached_62_before_1973_counts_to_65`). From the year he +reaches 62 the count now runs to that retirement year whatever the query, and a +death year ends it if earlier (404.110(b)(3)); disability keeps its count to +the onset year (404.132). `test_the_404_115_table_gives_each_cohort_its_count` +reads 404.115's table from the captured regulation and checks column II for a +living man and woman of every cohort at 62, 63, 64 and 66, and the death +columns of the 33 rows from 1893 through 1925. + +### A flagged prior needs one placement for both halves + +A flag records a prior "for which you were only insured under paragraph (c)", +so one placement has to pass a special route and fail 404.130(b) in the prior's +first quarter. `7b5b126a` checked the two halves apart, 404.130(c) on upper +credits and 404.130(b)'s failure on some placement. For a woman born 1962-06-28 +with a flagged prior in 1990Q2, 404.130(c) counts 28 quarters there and asks +14, and every placement reaches at most 11, while 404.130(b) holds on some +placements. Under UNKNOWN establishment `7b5b126a` computed her insured on the +subsequent-special rule, though either declared establishment refused. +`_flag_fits` now asks for one placement that does both, on every completion of +each year still open by the prior's start, and refuses by name where none does +(`test_a_flagged_prior_needs_paragraph_c_without_paragraph_b`). 404.130(b) +fails as credits fall and the route passes as they rise, so a middle completion +can fit where neither bound does (`test_only_a_middle_completion_fits_a_flag`). +Where every placement of the lower credits meets 404.130(b), the flag can't +stand, and the refusal names it before any count of completions +(`test_a_flag_every_completion_contradicts_refuses_by_that_name`). + +### A listed prior's basis and its refusal + +Past blindness with fully insured status alone dates from benefits payable in +January 1973 (RS 00301.150 A), so `_blind_basis` lets it begin a listed prior +only from then (low 21). A prior from December 1972 on 12 QCs from 1962 to 1964 +refuses by name, one from January 1973 computes +(`test_past_blindness_begins_a_prior_only_from_1973`), and a 1965 prior refuses +for FULLY as well (`test_a_1965_prior_cannot_rest_on_past_blindness`). + +Without that basis, a listed prior from July 1952 through 1955 can still rest +on RS 00301.480 B.1, which begins a period on its own counts. A listed prior's +establishment shows its holder met the route's application conditions, so such +a prior holds where B.1's counts hold at its start on every completion and no +completion has 20 of 40 in a quarter from its start through September 1960, +which RS 00301.480 A would read as excluding the route. Where only some +completion or one reading of A supports it, it refuses by that route's name, +and where every completion has 20 of 40 in a quarter the prior covers, both +readings exclude the route +(`test_a_pre1956_listed_prior_rests_on_rs00301_480`). A current period can then +begin after such a prior +(`test_a_listed_alternate_prior_lets_a_later_period_begin`). The reading +belongs to the register entry +`us:oasdi-insured-pre1956-alternate-any-quarter-scan`, whose marker now also +sits in `_prior_basis`. + +A listed prior that no completion supports rests on credits or facts the record +omits, and those could insure the current period as well. +`_refuse_unsupported_priors` now runs before the rule calls an established +period impossible or leaves its validity to UNKNOWN earnings, after any +deferred conversion's refusal, so the prior's named refusal keeps the row. A +woman born 1940-02-02 with eight QCs in 1968 and 1969, a 1970 prior and an +established 1977 period raised `InvalidFamilyInput` at `7b5b126a`, which let +past blindness begin the prior, and lost the row whatever 1974 to 1977 held. +She now refuses by the prior's name +(`test_an_unsupported_prior_refuses_before_unknown_earnings`). A fully-route +flag supplies fully insured status from a start the record doesn't give, so a +prior the flag can carry shows nothing missing (`_flag_carries_prior`, +`test_classification_oracle_fully_flag_can_carry_a_listed_prior`). + +### The other lows and nits + +These lows and nits change code, each with a test: + +- low 12: a declared period end after the statutory FRA end raises + `InvalidFamilyInput`, as a continuity date after it already did, where + `7b5b126a` capped it silently + (`test_declared_dates_past_the_statutory_end_are_input_errors`); +- low 16: a DIB entitlement month at or after FRA, and an RIB month before the + one in which the holder attains 62, raise `InvalidFamilyInput` (Act + 223(a)(1), 202(a)(2)), where `7b5b126a` let them decide CURRENTLY + (`test_entitlement_months_must_be_possible`); +- low 19: the pre-May-1983 refusal for a flagged prior fires only where the + holder's age-31 quarter begins before May 1983, since 404.130(c) decided an + onset before 31 under the earlier law too + (`test_the_pre_1983_refusal_needs_31_before_may_1983`); +- low 23: `fully_insured_requirement` runs the person and query checks + `insured_status` runs + (`test_the_requirement_helper_checks_what_insured_status_checks`); +- low 24: Act 213(a)(2)(B) bars a quarter after the death quarter from being a + QC, but wages paid then still count toward the year's total, so $7,770 paid + in 1968Q2 after a February death brings the year to the $7,800 maximum and + makes 1968Q1 a QC, where `7b5b126a` raised an input error + (`test_wages_paid_after_death_count_toward_the_year`); +- nit 25: the error for a quarterly QC or earnings before birth now names the + birth bound (`test_quarterly_bounds_name_themselves`). + +The rest change text: the `SIMPLIFIED_PRE1951` row says pre-1951 QC flags add +nothing to the 213(c) aggregate (low 8); the RS 00301.800 cohort reads from +404.110(b)(2)(ii) through (iv) (low 9); the witness passage states FULLY's +larger-margin convention (low 10); the DLI row states that DISABILITY can hold +at a quarter past FRA while the date takes the cap (low 11); the deferred +refusals read as conservative (low 14); the module docstring and the event +passage say a declared DIB or RIB month replaces the query event (low 15); the +sources README narrows what its tests check (low 17); the Joseph and Frank +entries read as placement-dependent intermediate counts (low 18); the +long-period register entry adds the third parse (low 22); the fiscal-year +helper names the 1971 to 1972 gap (nit 26); the examples cite RS 00301.345 +B.2.g and log Mary Brown's count (nit 27); and the note corrects the round 21 +and 22 slips the review found (nit 28). +`test_the_note_cites_only_tests_that_exist` checks that every test this note +cites exists and that it cites no scratch file, and the PR body carries the +ledger path and current counts (low 20, nit 30). + +### Renamed, retired and superseded + +Round 23 renames these tests, whose old names described the overlap bar or a +reading this round corrects: + +| Module | Name at `7b5b126a` | Round 23 name | +| --- | --- | --- | +| base | test_joseph_subsequent_poms_140_example_6_endpoint_erratum | `test_joseph_subsequent_poms_140_example_6_endpoint_placement` | +| base | test_unknown_upper_bound_respects_exit_quarter | `test_unknown_exit_year_keeps_every_quarter_of_its_year` | +| classification oracle | test_classification_oracle_alternate_needs_clear_start_before_1956 | `test_classification_oracle_alternate_can_start_in_a_prior_end_quarter` | +| classification oracle | test_classification_oracle_blind_ordinary_onset_cannot_be_delayed | `test_classification_oracle_blind_ordinary_onset_starts_after_prior` | +| classification oracle | test_classification_oracle_fully_flag_cannot_delay_an_insured_onset | `test_classification_oracle_fully_flag_keeps_an_insured_onset` | +| round 11 | test_fixed_overlap_precedes_every_flag_and_foreign_route | `test_a_prior_ending_in_the_onset_quarter_leaves_a_valid_start`; `test_a_prior_ending_in_the_onset_quarter_keeps_every_route_refusal` | +| round 12 | test_candidate_inside_prior_period_does_not_supply_recent_witness | `test_an_onset_in_a_prior_end_quarter_can_supply_the_recent_witness` | +| round 13 | test_disability_witness_uses_the_legal_annual_start_filling | `test_disability_witness_counts_the_quarter_a_prior_ended` | +| round 13 | test_post1955_clear_start_cannot_replace_overlapped_alternate | `test_every_test_refuses_a_shared_quarter_alternate_by_name` | +| round 13 | test_review_alternate_start_must_clear_same_prior_overlap | `test_an_alternate_start_can_share_the_quarter_a_prior_ended` | +| round 4 routes | test_possible_lower_earnings_filling_prevents_upper_overlap_input_error | `test_every_onset_year_filling_starts_a_valid_period` | +| round 4 routes | test_unknown_earnings_can_avoid_derived_prior_quarter_overlap | `test_unknown_onset_year_earnings_decide_the_current_start` | +| round 6 ordering | test_deferred_quarter_fillings_keep_fixed_minimum_and_valid_middle | `test_deferred_quarter_fillings_survive_a_shared_onset_quarter` | +| round 6 ordering | test_unresolved_overlap_keeps_original_deferred_refusal | `test_many_unknown_years_keep_original_deferred_refusal` | +| QC | test_death_future_exit_and_disability_endpoint_exclusions | `test_death_future_and_disability_endpoint_exclusions` | +| sources | test_rs00301_800_pdf_footnote_misprints_the_1913_male_age_65_cohort | `test_rs00301_800_pdf_footnote_misdates_the_male_age_65_cohort` | + +Old names appear without code marks, so the citation test reads only live +names. The classification oracle adds +`test_classification_oracle_fully_flag_can_carry_a_listed_prior`. + +Fourteen tests held the overlap bar, and round 23 retires them with it. Round +14's seven (first_successful_placement_cannot_settle_status, +one_treatment_overlaps_and_the_other_leaves_a_clear_start, +round_thirteen_annual_start_needs_named_refusal and four unchanged_..._overlap +cases) give way to eight on the shared quarter: +`test_a_shared_onset_quarter_is_a_valid_start`, +`test_one_onset_year_qc_starts_the_period_on_the_onset_day`, +`test_two_onset_year_qcs_leave_the_start_to_placement`, +`test_round_thirteen_annual_start_computes_in_the_shared_quarter`, +`test_ordinary_insurance_in_a_shared_onset_quarter_keeps_flag_refusal`, +`test_1962_ordinary_insurance_in_a_shared_quarter_fixes_start`, +`test_blind_fully_insured_onset_in_a_shared_quarter_starts_there` and +`test_the_treatment_that_insures_the_shared_quarter_fixes_the_start`. Round 5's +four overlap searches give way to +`test_shared_quarter_declaration_exactly_matches_every_quarter_filling`, +`test_an_april_end_needs_the_onset_quarter_insured`, +`test_any_1972_qc_starts_a_period_before_a_december_end` and +`test_many_unknown_years_keep_one_earnings_refusal_row`, and round 6's three +fixed-overlap orderings give way to +`test_a_prior_ending_in_the_onset_quarter_classifies_like_one_before`, +`test_a_shared_end_quarter_leaves_validity_to_unknown_credits` and +`test_shared_end_quarter_validity_stays_with_unknown_credits`. + +These passages above record earlier rounds and stay as written, and round 23 +supersedes them: round 13's list of fully-route first-onset overlaps and its +oracle's later ordinary start after an overlapping onset; round 15's remark +that round 14 stopped placements mixing only where the favorable start +overlapped a prior; round 16's stress generator, whose overlapping prior now +ends in the onset quarter (`shared`); and round 19's statement that the round +17 ruling stands, since round 23 lists the third parse in the register for Max +(d1920). Round 23 rewrites the round 5 and round 6 grids and examples in place, +and retires I13 and B15. + +### Mutations + +The list of mutations (`round_23_mutations` in +`track_b_insured_status_mutations.json`) takes round 22's 70 and adds 29 of +this round's own, for 99. Round 22's anchors still hold for 53 of the 70. The +other 17 touched code round 23 rewrote, and each keeps its intent at the code +that now does that job: two at the binding check, which now also asks for a +basis; five in `_keeps_priors` and nine in `_prior_basis`, which now pass +`options` and whose unflagged loop reads `_blind_basis`; and +`first_search_drops_binding`, since the first search now runs once with the +binding priors and once without. Each of the 70 ran through the tests that +killed it in round 22, and through their modules and round 23's where those +passed, and 69 failed a named test. `flagged_ignores_ordinary_rule`, which +drops a flagged prior's every-placement 404.130(b) check, now differs from the +rule only where more than 4,096 completions stand open: it refuses on their +number instead of the flag, and +`test_a_flag_every_completion_contradicts_refuses_by_that_name` kills it. + +Round 23's own 29 undo one change each. `m1_flag`, `m1_open_basis` and +`m1_settle` drop the current period's flag, close an open basis, or skip the +basis check. `m2_listed` and `m2_current` bar a shared quarter again. `m3_exit` +and `m13_birth` restore the exit-quarter and birth-quarter bars. `m4_rank` +drops the earlier-quarter rank, `m5_earliest` the onset-quarter bound under +UNKNOWN priors, and `basis_split_unreported` and `basis_split_always` misreport +the basis split. `m6_men` ends a living man's count at the query. `m7_flagfits` +drops the one-placement check, and `flag_middle` searches only the bounds. +`precedence_possible` and `precedence_unknown` let the input error or the +UNKNOWN-earnings refusal come first. `pre1956_scan` scans past the quarters the +prior covers, and `pre1956_none` refuses the B.1 prior. `low21` lets past +blindness begin a prior before 1973, and `nit29` restores the general detail. +`low12`, `low16_dib`, `low16_rib`, `low19`, `low23`, `low24` and `nit25` undo +each low's check. `first_onset_short` and `first_onset_odd` move 404.130(c)'s +12-quarter floor or round its half up. Each of the 29 fails round 23's module. + +Against `7b5b126a`, 42 of round 23's 66 cases fail. The 24 that pass hold +behavior `7b5b126a` already had: the example 7 quote, the seven middle +completions and the two contradicted flags, the January 1973 prior, the +pre-1956 prior that computes, the seven published first onsets, the two valid +entitlement months, two quarterly bounds and the note's citations. + +These tests execute the invariants this round adds: + +- a current period that began before 31 on 404.130(c) alone, its holder not + blind, counts as a flagged prior for the quarters after it and gives the same + date as that prior listed + (`test_an_ended_current_period_counts_as_the_prior_it_becomes`, + `test_a_period_begun_on_paragraph_c_alone_opens_paragraph_d_after_it`, and + the stress oracle through `check`); +- where placement or an UNKNOWN year decides that basis and the bases give + different dates, the date refuses by name and keeps its row + (`test_a_placement_or_year_that_decides_the_basis_refuses`); +- periods share no day, and a period may begin in the quarter a prior ended + (`test_rs00301_140_example_7_begins_on_the_onset_day`, + `test_any_onset_after_the_prior_day_keeps_its_own_start`, + `test_periods_still_may_not_share_a_day`); +- the exit month moves no result within its year, and neither a birth nor an + exit bars an annual QC from a begun quarter of its own year + (`test_the_exit_month_moves_nothing_in_its_year`, + `test_an_exit_year_credits_any_begun_quarter`, + `test_a_birth_year_credits_quarters_before_the_birth`); +- DISABILITY reports the earliest first insured quarter a kept filling attains, + and its range spans every basis a binding prior can rest on and, under + UNKNOWN priors, reaches the onset quarter + (`test_a_binding_prior_keeps_the_earliest_qualifying_quarter`, + `test_a_prior_basis_split_widens_the_qualifying_quarters`, + `test_unknown_priors_reach_the_onset_quarter`); +- a living man born before January 2, 1913 counts elapsed years to 65 or 1975 + from the year he reaches 62, and each 404.115 cohort gets its column + (`test_the_404_115_table_gives_each_cohort_its_count`, + `test_a_man_who_reached_62_before_1973_counts_to_65`); +- a flagged prior stands only on a placement where a special route passes and + 404.130(b) fails + (`test_a_flagged_prior_needs_paragraph_c_without_paragraph_b`, + `test_only_a_middle_completion_fits_a_flag`, + `test_a_flag_every_completion_contradicts_refuses_by_that_name`); +- a listed prior no completion supports refuses by name before any input error + or UNKNOWN-earnings refusal, and the row keeps its weight + (`test_an_unsupported_prior_refuses_before_unknown_earnings`, + `test_past_blindness_begins_a_prior_only_from_1973`, + `test_a_1965_prior_cannot_rest_on_past_blindness`). + ## Not in scope No real data, population evaluation, baseline claiming hazard, behavioral diff --git a/src/populace_dynamics/track_b/_insured_status_qc.py b/src/populace_dynamics/track_b/_insured_status_qc.py index 185bdcc42..393e17b6f 100644 --- a/src/populace_dynamics/track_b/_insured_status_qc.py +++ b/src/populace_dynamics/track_b/_insured_status_qc.py @@ -183,19 +183,18 @@ def _allowed_quarters( *, through_quarter: int, death_quarter: int | None = None, - coverage_end_quarter: int | None = None, disability_periods: tuple[tuple[int, int], ...] = (), ) -> tuple[int, ...]: - """404.146: begun, not after death/exit, outside disability interiors. + """404.146: begun, not after death, outside disability interiors. Disability endpoints themselves remain eligible. A caller that elects not to take a period into consideration under 404.146(d)(2) omits it. - Coverage-end is the explicit entrant/emigrant contract, not an additional - statutory disability exclusion. + A coverage exit bars only later years, which the history leaves out, so + it bars no quarter of its own year here. """ last = min( value - for value in (through_quarter, death_quarter, coverage_end_quarter) + for value in (through_quarter, death_quarter) if value is not None ) # Source conflict us:oasdi-insured-disability-period-endpoint-quarters @@ -289,6 +288,10 @@ def _pre1978_taxable_qcs( fifth calendar quarter; otherwise SEI is allocated to at most four. Wage QCs themselves are supplied separately by their actual quarters. """ + # RS 00301.345 B.2 sets $7,800 for a taxable year ending before 1972 and + # $9,000 for one beginning in 1972, so a fiscal year from 1971 into 1972 + # fits neither, and this helper takes 1972's $9,000 there. Only tests + # call it: public calls refuse fiscal taxable years. limit_year = start.year if start.year >= 1972 else end.year if self_employment + wages >= _annual_wage_limit(limit_year): return tuple(range(_date_quarter(start), _date_quarter(end) + 1)) diff --git a/src/populace_dynamics/track_b/insured_status.py b/src/populace_dynamics/track_b/insured_status.py index 8eee58a3b..6e251c656 100644 --- a/src/populace_dynamics/track_b/insured_status.py +++ b/src/populace_dynamics/track_b/insured_status.py @@ -43,23 +43,22 @@ envelope requires six QCs feasible by the immutable start horizon, except blindness with a fully-insured-only flag. UNKNOWN prior history cannot remove this floor. An established period's alternate witness must use a -single start that also clears prior-period overlap and the 1955 date limit; -credited endpoints remain eligible for its continuous clock. +single start within the 1955 date limit; credited endpoints remain eligible +for its continuous clock. UNKNOWN prior history also obeys a joint optimistic-clock proof: even deleting every removable uncredited quarter cannot rescue a declaration whose same credits fail the current route. Past blindness is allowed as an unresolved prior basis, including in the earliest-prior emptiness proof. -Known-history fully-route scans fix the first start only when ordinary -insurance holds for that filling and prior treatment. A flag's first -fully insured quarter is unknown, including for blindness. When a clear -first start depends on annual placement or prior treatment after a favorable -overlapping start, construction retains a named refusal rather than -selecting a filling that could change another returned status. +A flag's first fully insured quarter is unknown, including for blindness. +A period may begin in the quarter a prior period ended (RS00301.140 example +7), so no start overlaps a prior period. The declared pre1956 flag adds no route beyond the automatic alternate. Flag-specific conditions remain declared facts rather than adjudicated rules. Short DIB-entitled prior periods remain possible. Observable specialist credit -alternatives cannot silently produce ordinary-only uninsured answers. The -query month is a hypothetical entitlement month, not medical or +alternatives cannot silently produce ordinary-only uninsured answers. With +no declared death, RIB or DIB month, the query month is a hypothetical +entitlement month; a declared one replaces it for currently insured status, +even where the worker has earned QCs since. Neither is medical or administrative adjudication. Annual QC assignment is favorable and retrospective; callers must supply only information available at their decision time. Each test returns its own assignment witness. @@ -78,7 +77,7 @@ from datetime import date, timedelta from enum import Enum from fractions import Fraction -from itertools import combinations, product +from itertools import product from math import prod from types import MappingProxyType @@ -490,6 +489,15 @@ def __post_init__(self): "Established period begins after its statutory FRA end" ) fra_end = fra.replace(day=1) - timedelta(days=1) + if ( + self.current_disability_period_end is not None + and self.current_disability_period_end > fra_end + ): + # 404.321(b) ends a period by the month before FRA, so no + # completion has a later end. + raise InvalidFamilyInput( + "Current period ends after its statutory FRA end" + ) _fact_provenance( self.current_disability_period_continues_through_provenance, self.current_disability_period_continues_through_convention_id, @@ -533,8 +541,10 @@ def __post_init__(self): self.death_date is not None and period.end > self.death_date ): raise InvalidFamilyInput("Disability period outside lifetime") - if i and _qid(period.start) <= _qid(periods[i - 1].end): - raise InvalidFamilyInput("Disability periods overlap quarters") + # One period may end in the quarter the next begins: 404.321(a) + # starts a period on its onset day (RS00301.140 example 7). + if i and period.start <= periods[i - 1].end: + raise InvalidFamilyInput("Disability periods overlap") if period.special_insured and _qid(period.start) >= _qid( _attain(self.birth_date, 31) ): @@ -558,6 +568,21 @@ def __post_init__(self): and event > self.death_date.replace(day=1) ): raise InvalidFamilyInput("Entitlement outside lifetime") + # Disability benefits end the month before FRA (Act 223(a)(1)), and + # no old-age benefit begins before the month of attaining 62 (Act + # 202(a)(2)). The field holds the entitlement the caller wants the + # CURRENTLY test to follow. + if ( + self.dib_entitlement_month is not None + and self.dib_entitlement_month >= fra.replace(day=1) + ): + raise InvalidFamilyInput("DIB entitlement at or after FRA month") + if ( + self.rib_entitlement_month is not None + and self.rib_entitlement_month + < _attain(self.birth_date, 62).replace(day=1) + ): + raise InvalidFamilyInput("RIB entitlement before age 62") object.__setattr__(self, "prior_disability_periods", tuple(periods)) @@ -613,16 +638,25 @@ class InsuredStatus(_SealedResult): def _requirement(person, at, periods=(), *, onset=True, for_disability=False): start = max(1951, _attain(person.birth_date, 21).year + 1) end = min(at.year, _attain(person.birth_date, 62).year) + living = person.death_date is None or person.death_date > at if person.sex is Sex.MALE and person.birth_date < date(1913, 1, 2): - end = min( - at.year, - ( - _attain(person.birth_date, 65).year - if person.birth_date < date(1911, 1, 2) and not for_disability - else 1975 - ), - ) - if person.death_date is not None: + retirement = ( + _attain(person.birth_date, 65).year + if person.birth_date < date(1911, 1, 2) and not for_disability + else 1975 + ) + # 404.110(b)(2)(iii)-(iv) end a living man's old-age count at the + # year he reaches retirement age, 65 or 1975, once he can claim at + # 62. Before 62, or at death (404.110(b)(3)), the query or death year + # ends it first. 404.132 keeps disability's count to the onset year. + end = ( + retirement + if living + and not for_disability + and at.year >= _attain(person.birth_date, 62).year + else min(at.year, retirement) + ) + if person.death_date is not None and not living: end = min(end, person.death_date.year) elapsed = sum( not any(a.year <= year <= b.year for a, b in periods) @@ -633,24 +667,11 @@ def _requirement(person, at, periods=(), *, onset=True, for_disability=False): @_validated_entry def fully_insured_requirement(person: Person, month: date) -> int: - """One QC per elapsed year, bounded by six and forty (214(a)).""" - _month(month, "month") - if ( - person.disability_onset is not None - and person.current_disability_period_provenance is None - ): - raise InvalidFamilyInput( - "Declare current disability period establishment" - ) - if month < person.birth_date.replace(day=1): - raise InvalidFamilyInput("Query precedes birth") - if ( - person.disability_onset is not None - and person.disability_onset.replace(day=1) > month - ): - raise InvalidFamilyInput("Disability onset follows query month") - if any(p.end >= month for p in person.prior_disability_periods): - raise InvalidFamilyInput("Prior disability period follows query month") + """One QC per elapsed year, bounded by six and forty (214(a)). + + It runs the person and query checks ``insured_status`` runs. + """ + _validate_person_at(person, month) if ( person.prior_disability_periods_provenance is EarningsProvenance.UNKNOWN @@ -682,7 +703,8 @@ def qc_amount_from_nawi(nawi: Fraction, prior_amount: int) -> int: return _qc_amount_from_nawi(nawi, prior_amount) -def _validate_history(person, years, month, coverage_end_month, credits): +def _validate_person_at(person, month): + """Person and query checks every public entry runs.""" _month(month, "month") if ( person.disability_onset is not None @@ -707,6 +729,18 @@ def _validate_history(person, years, month, coverage_end_month, credits): ) ): raise InvalidFamilyInput("Entitlement follows query month") + for period in person.prior_disability_periods: + if period.end >= month or ( + person.disability_onset is not None + and period.end >= person.disability_onset + ): + raise InvalidFamilyInput( + "Prior disability period must precede current event" + ) + + +def _validate_history(person, years, month, coverage_end_month, credits): + _validate_person_at(person, month) if coverage_end_month is not None: _month(coverage_end_month, "coverage_end_month") if coverage_end_month < person.birth_date.replace(day=1): @@ -734,14 +768,7 @@ def _validate_history(person, years, month, coverage_end_month, credits): "Every coverage year must be declared; missing=" f"{sorted(expected - set(years))}, extra={sorted(set(years) - expected)}" ) - for period in person.prior_disability_periods: - if period.end >= month or ( - person.disability_onset is not None - and period.end >= person.disability_onset - ): - raise InvalidFamilyInput( - "Prior disability period must precede current event" - ) + first = _qid(person.birth_date) for year, row in years.items(): if year < 1978: if row.qc_count is not None or row.wages is not None: @@ -756,26 +783,29 @@ def _validate_history(person, years, month, coverage_end_month, credits): raise InvalidFamilyInput( "Post1977 agricultural wages belong in wages" ) - cutoff = min( + # Act 213(a)(2)(B)(i) bars a quarter after death from being a QC, + # but wages paid then still count toward the year's total (B)(ii), + # and ``_allowed_quarters`` drops the quarter from every assignment. + paid = min( _qid(month), - _qid(person.death_date) if person.death_date else _qid(month), _qid(coverage_end_month) if coverage_end_month else _qid(month), ) - if row.qc_quarters is not None: - if any( - flag and not _qid(person.birth_date) <= year * 4 + i <= cutoff - for i, flag in enumerate(row.qc_quarters) - ): - raise InvalidFamilyInput( - "Quarterly QCs declared after coverage ends" - ) - if row.quarterly_wages is not None: - if any( - value and not _qid(person.birth_date) <= year * 4 + i <= cutoff - for i, value in enumerate(row.quarterly_wages) - ): + cutoff = min( + paid, + _qid(person.death_date) if person.death_date else paid, + ) + for values, last, label in ( + (row.qc_quarters, cutoff, "Quarterly QCs"), + (row.quarterly_wages, paid, "Quarterly earnings"), + ): + quarters = [ + year * 4 + i for i, value in enumerate(values or ()) if value + ] + if any(quarter < first for quarter in quarters): + raise InvalidFamilyInput(f"{label} declared before birth") + if any(quarter > last for quarter in quarters): raise InvalidFamilyInput( - "Quarterly earnings declared after coverage ends" + f"{label} declared after coverage ends" ) @@ -797,9 +827,14 @@ def _coverage_checks(person, years, month, credits): InsuredUnsupportedReason.HISTORICAL_BLINDNESS, "Pre1973 blindness tests", ) - if any( - p.special_insured for p in person.prior_disability_periods - ) and month < date(1983, 5, 1): + # 404.130(d) came with the 1983 amendments and applies only from the + # quarter of attaining 31; earlier quarters keep 404.130(c), which + # pre-1983 law also had. + if ( + any(p.special_insured for p in person.prior_disability_periods) + and month < date(1983, 5, 1) + and _qdate(_qid(_attain(person.birth_date, 31))) < date(1983, 5, 1) + ): _refuse( InsuredUnsupportedReason.HISTORICAL_SUBSEQUENT, "Pre1983 subsequent-period amendments", @@ -1037,22 +1072,14 @@ def _pre1956_alternate_possible( last = min(last, covered) lower = credits if lower_credits is None else lower_credits # Source conflict us:oasdi-insured-pre1956-alternate-any-quarter-scan - for quarter in range( - _qid(person.disability_onset), min(_qid(last), 1960 * 4 + 2) + 1 + if _twenty_of_forty_by( + person, + lower, + _qid(person.disability_onset), + min(_qid(last), 1960 * 4 + 2), + exit_month, ): - for use_periods in ( - (True, False) if person.prior_disability_periods else (True,) - ): - rows, periods = _world( - person, lower, quarter, exit_month, use_periods - ) - for boundary in _boundary_variants(rows, periods): - window = _window(quarter, 40, periods, boundary) - if ( - len(set(_assignment(rows, window, boundary)) & set(window)) - >= 20 - ): - return False + return False if person.current_disability_period_established: # RS00301.480 B.1: a freeze cannot begin before 1952-07-01. # An independent alternate route still must start before the @@ -1060,39 +1087,60 @@ def _pre1956_alternate_possible( month = _current_period_start_horizon(person, month) first = max(_qid(person.disability_onset), 1952 * 4 + 2) last = min(_qid(month), 1955 * 4 + 3) + return any( + _pre1956_counts(person, credits, quarter, exit_month) + for quarter in range(first, last + 1) + ) + + +def _twenty_of_forty_by(person, credits, first, last, exit_month): + """Whether some quarter from ``first`` through ``last`` has 20 of 40.""" for quarter in range(first, last + 1): - # One start must satisfy both the alternate and fixed chronology. - if person.current_disability_period_established and not ( - _outside_prior_periods(person, quarter) - ): - continue - # RS00301.132 B.2/C.2: all prior periods are used or disregarded - # for the continuous clock too; credited endpoints stay eligible. for use_periods in ( (True, False) if person.prior_disability_periods else (True,) ): rows, periods = _world( person, credits, quarter, exit_month, use_periods ) - target = tuple(range(1951 * 4, quarter)) for boundary in _boundary_variants(rows, periods): - assigned = set(_assignment(rows, target, boundary)) - continuous = tuple( - q - for q in target - if not any( - a <= q <= b and q not in assigned for a, b in periods - ) - ) + window = _window(quarter, 40, periods, boundary) if ( - len(assigned) >= 20 - and len(continuous) >= 6 - and set(continuous) <= assigned + len(set(_assignment(rows, window, boundary)) & set(window)) + >= 20 ): return True return False +def _pre1956_counts(person, credits, quarter, exit_month): + """Whether RS00301.480 B.1's counts can hold at one start quarter.""" + # RS00301.132 B.2/C.2: all prior periods are used or disregarded + # for the continuous clock too; credited endpoints stay eligible. + for use_periods in ( + (True, False) if person.prior_disability_periods else (True,) + ): + rows, periods = _world( + person, credits, quarter, exit_month, use_periods + ) + target = tuple(range(1951 * 4, quarter)) + for boundary in _boundary_variants(rows, periods): + assigned = set(_assignment(rows, target, boundary)) + continuous = tuple( + q + for q in target + if not any( + a <= q <= b and q not in assigned for a, b in periods + ) + ) + if ( + len(assigned) >= 20 + and len(continuous) >= 6 + and set(continuous) <= assigned + ): + return True + return False + + def _credits(year, row, upper): if row.provenance is EarningsProvenance.UNKNOWN: return (), 4 if upper else 0 @@ -1171,6 +1219,12 @@ def _world( else () ) rows = {} + # RS00301.230 B assigns an annual QC to "any quarter in the calendar + # year", subject to RS00301.240, which bars a quarter not yet begun, one + # after death and a disability period's interior. Neither the year a + # person is born nor the year coverage ends adds a bar. The history stops + # at the exit year (``_validate_history``), so the exit bars every later + # year, and declared quarterly credits after it are input errors. for year, (fixed, flexible) in credits.items(): if not include_zero and not fixed and not flexible: continue @@ -1180,10 +1234,8 @@ def _world( death_quarter=( _qid(person.death_date) if person.death_date else None ), - coverage_end_quarter=_qid(exit_month) if exit_month else None, disability_periods=periods, ) - allowed = tuple(q for q in allowed if q >= _qid(person.birth_date)) rows[year] = (fixed, flexible, allowed) return rows, periods @@ -1595,6 +1647,49 @@ def _period_end_unknown(person, month): ) +def _current_period_special( + person, credits, quarter, month, exit_month, use_periods_only=None +): + """Whether the current period began on 404.130(c) alone. + + 404.130(d)(1) reaches a later disability after "a prior period of + disability established which began before age 31 and for which you were + only insured under paragraph (c)", and Act 223(c)(1)(B)(iii) says the + same. The rule begins the current period itself (404.321(a)), so it + records that fact as ``special_insured``: the period began before the + quarter its holder attains 31, its holder wasn't blind (404.130(e) asks + only for fully insured status), and 404.130(b) failed in its first + quarter. Returns None when annual placement decides whether 404.130(b) + held there; with listed priors that stays open whenever some placement + meets 404.130(b). + """ + if person.statutory_blindness or _qid(quarter) >= _qid( + _attain(person.birth_date, 31) + ): + return False + if not _witness( + person, + credits, + quarter, + exit_month, + InsuredTest.DISABILITY, + ordinary_only=True, + use_periods_only=use_periods_only, + )[0]: + return True + if not person.prior_disability_periods and _every_placement_passes( + person, + credits, + quarter, + month, + exit_month, + InsuredTest.DISABILITY, + ordinary_only=True, + ): + return False + return None + + def _with_current_period( person, credits, month, exit_month, *, use_periods_only=None ): @@ -1614,44 +1709,16 @@ def _with_current_period( raise InvalidFamilyInput( "Established current period has no insured disabled quarter" ) - if use_periods_only is None and not _outside_prior_periods( - person, _qid(quarter) - ): - # A clear first start proves possibility, not a status shared by - # every filling. Keep the row when annual placement or treatment - # changes that start (404.321(a); RS00301.230). - rows, _ = _world(person, credits, _qid(horizon), exit_month, False) - options = [_assignment_candidates(*row) for row in rows.values()] - if prod(map(len, options)) > 4096: - _refuse( - InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, - "More than 4096 first-start annual placements", - ) - for choices in product(*options): - filling = { - year: (choice, 0) - for year, choice in zip(rows, choices, strict=True) - } - for treatment in (True, False): - try: - _with_current_period( - person, - filling, - month, - exit_month, - use_periods_only=treatment, - ) - except InvalidFamilyInput: - continue - _refuse( - InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, - "First insured start depends on annual placement " - "or prior treatment", - ) - return _complete_current_period(person, quarter) + special = _current_period_special( + person, credits, quarter, month, exit_month, use_periods_only + ) + # A filling fixes every year that can move 404.130(b) in the first + # quarter, so None there means 404.130(b) held. ``insured_status`` checks + # flexible credits for a split. + return _complete_current_period(person, quarter, special=special is True) -def _complete_current_period(person, quarter): +def _complete_current_period(person, quarter, special=False): fra = _fra_date(person) # 416(i)(2)(C), 404.321(a): onset day if insured then, otherwise # first day of the first later insured quarter. Application/duration @@ -1681,7 +1748,7 @@ def _complete_current_period(person, quarter): and person.current_disability_period_continues_through < start ): raise InvalidFamilyInput("Period continuity precedes insured start") - period = DisabilityPeriod(start, end) + period = DisabilityPeriod(start, end, special_insured=special) completed = replace( person, prior_disability_periods=person.prior_disability_periods + (period,), @@ -1749,14 +1816,16 @@ def _prior_passes(person, credits, index, exit_month, *, blind, **options): )[0] -def _keeps_priors(person, filling, binding, exit_month): +def _keeps_priors(person, filling, binding, exit_month, **options): """Whether one filling lets each binding prior begin on its basis. A flagged prior's holder "were only insured under paragraph (c)" (404.130(d)(1)), so that holder passes a special route and not 404.130(b). """ return all( - _prior_passes(person, filling, index, exit_month, blind=blind) + _prior_passes( + person, filling, index, exit_month, blind=blind, **options + ) and not ( person.prior_disability_periods[index].special_insured and _prior_passes( @@ -1766,6 +1835,7 @@ def _keeps_priors(person, filling, binding, exit_month): exit_month, blind=False, ordinary_only=True, + **options, ) ) for index, blind in binding @@ -1796,47 +1866,219 @@ def _every_placement_begins( ) -def _prior_basis(person, lower, upper, index, month, exit_month): +def _prior_basis(person, lower, upper, index, month, exit_month, **options): """Whether past blindness alone can support a listed prior's start. A period begins in a quarter its holder was insured (404.320(b)(2), - 404.321(a)). A flag records a prior "for which you were only insured under - paragraph (c)" (404.130(d)(1)), so no placement supports a flagged prior - if none passes a route or all of them pass 404.130(b), and 404.130(c) - can't begin an unflagged prior alone. The record doesn't say whether an - unflagged prior rested on past blindness, which asks only for fully - insured status (404.130(e)), or on 404.130(b), or (d) after a flagged - prior, which ask for that and more. A result has to stand on each basis some placement - allows. Every placement 404.130(b) or (d) allows also passes 404.130(e), - so a filling that keeps the prior on them speaks for both, and they hold - the prior wherever a placement meets them. A prior no placement supports - rests on credits or facts this record omits, and those could move other - results, so the rule refuses it by name. Upper credits bound every - completion of an UNKNOWN year. + 404.321(a)). A flag records a prior "for which you were only insured + under paragraph (c)" (404.130(d)(1)), so a flagged prior needs one + placement that passes a special route and fails 404.130(b) + (``_flag_fits``), and 404.130(c) can't begin an unflagged prior alone. + The record doesn't say whether an unflagged prior rested on past + blindness, which asks only for fully insured status (404.130(e)), or + on 404.130(b), or (d) after a flagged prior, which ask for that and + more. A result has to stand on each basis some placement allows. Every + placement 404.130(b) or (d) allows also passes 404.130(e), so a + filling that keeps the prior on them speaks for both, and they hold + the prior wherever a placement meets them. + + Past blindness supports a prior only from January 1973 + (``_blind_basis``). RS00301.480 B.1 can begin a period from July 1952 + through 1955 on its own counts, and a listed prior's establishment shows + its application conditions were met. Such a prior holds, and returns + None because placement can't move it, where B.1's counts hold at its + start on every completion and no completion has 20 of 40 in a quarter + from its start through September 1960, which RS00301.480 A would read + as excluding the route. Where only some completion or one reading of A + supports it, it refuses by that route's name. Where every completion + has 20 of 40 in a quarter the prior covers, both readings exclude the + route. Any other prior no placement supports rests on credits or facts + this record omits, and those could move other results, so the rule + refuses it by name. Upper credits bound every completion of an UNKNOWN + year. ``options`` reach every route test, so + ``ignore_fully_insured`` asks whether the prior's counts alone hold. """ if person.prior_disability_periods[index].special_insured: - if _prior_passes( - person, upper, index, exit_month, blind=False - ) and not _every_placement_begins( - person, - lower, - index, - month, - exit_month, - blind=False, - ordinary_only=True, + if ( + _prior_passes( + person, upper, index, exit_month, blind=False, **options + ) + and not _every_placement_begins( + person, + lower, + index, + month, + exit_month, + blind=False, + ordinary_only=True, + **options, + ) + and _flag_fits( + person, lower, upper, index, month, exit_month, **options + ) ): return False else: - for blind in (False, True): - if _prior_passes(person, upper, index, exit_month, blind=blind): + for blind in ( + (False, True) if _blind_basis(person, index) else (False,) + ): + if _prior_passes( + person, upper, index, exit_month, blind=blind, **options + ): return blind + period = person.prior_disability_periods[index] + earlier = replace( + person, + prior_disability_periods=person.prior_disability_periods[:index], + ) + first = _qid(period.start) + # Every completion of the prior covers its start through two months + # before its end (404.321(b)), short of FRA, and both readings of + # RS00301.480 A count 20 of 40 there. + covered = min( + max(period.start.replace(day=1), _two_months_before(period.end)), + _fra_date(person).replace(day=1) - timedelta(days=1), + ) + if ( + date(1952, 7, 1) <= period.start < date(1956, 1, 1) + and _pre1956_counts(earlier, upper, first, exit_month) + and not _twenty_of_forty_by( + earlier, + lower, + first, + min(_qid(covered), 1960 * 4 + 2), + exit_month, + ) + ): + # Source conflict us:oasdi-insured-pre1956-alternate-any-quarter-scan + if _pre1956_counts( + earlier, lower, first, exit_month + ) and not _twenty_of_forty_by( + earlier, upper, first, 1960 * 4 + 2, exit_month + ): + return None + _refuse( + InsuredUnsupportedReason.DISABILITY_BEFORE_1956, + "RS00301.480 may have begun a listed prior before 1956", + ) _refuse( InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, "No annual placement supports a listed prior's first insured quarter", ) +def _refuse_unsupported_priors(person, lower, upper, month, exit_month): + """Refuse by name where a listed prior shows the record is incomplete. + + A listed prior that no completion of these credits supports rests on + credits or facts the record omits (``_prior_basis``), and those could + insure the current period as well. So before credits alone call an + established current period impossible, or leave its validity to UNKNOWN + earnings, each listed prior's basis is checked, and a prior's named + refusal keeps the row. A fully-route flag supplies fully insured status + from a start the record doesn't give, as the possibility check reads it + (``_recent_rule_possible``), so a prior the flag can carry shows nothing + missing. + """ + flagged = bool(person.conditions & _FULLY_INSURED_ROUTE_CONDITIONS) + for index in range(len(person.prior_disability_periods)): + try: + _prior_basis(person, lower, upper, index, month, exit_month) + except InsuredConfigurationUnsupported: + if not ( + flagged + and _flag_carries_prior( + person, lower, upper, index, month, exit_month + ) + ): + raise + + +def _flag_carries_prior(person, lower, upper, index, month, exit_month): + """Whether a listed prior begins once a flag supplies fully insured status. + + Past blindness asks for nothing more (404.130(e)); other bases still need + their counts on some completion. + """ + if _blind_basis(person, index): + return True + try: + _prior_basis( + person, + lower, + upper, + index, + month, + exit_month, + ignore_fully_insured=True, + ) + except InsuredConfigurationUnsupported: + return False + return True + + +def _blind_basis(person, index): + """Whether past blindness alone can be a listed prior's basis. + + A flagged prior rested on 404.130(c) alone (404.130(d)(1)). Blindness + with fully insured status alone dates from benefits payable January 1973 + (RS00301.150 A), and the rule refuses current blindness before then. + """ + period = person.prior_disability_periods[index] + return not period.special_insured and period.start >= date(1973, 1, 1) + + +def _flag_fits(person, lower, upper, index, month, exit_month, **options): + """Whether one placement begins a flagged prior on 404.130(c) alone. + + The flag records a prior "for which you were only insured under paragraph + (c)" (404.130(d)(1)), so one placement has to pass a special route and + fail 404.130(b) in the prior's first quarter. Where 404.130(b) fails on + every placement, the placement that passes a route is that one. + Otherwise the placements of the years that can move the prior's start + are searched, on every completion of each year whose count is open by + then. 404.130(b) fails as credits fall and the route passes as they rise, + so a middle completion can fit where neither bound does. A flag no + completion supports refuses by name, which keeps the row. + """ + if not _prior_passes( + person, + upper, + index, + exit_month, + blind=False, + ordinary_only=True, + **options, + ): + return True + binding = ((index, False),) + sensitive = _prior_sensitive_years(person, binding) + start = person.prior_disability_periods[index].start.year + open_years = [ + year for year in upper if year <= start and lower[year] != upper[year] + ] + counts = [range(lower[y][1], upper[y][1] + 1) for y in open_years] + if prod(map(len, counts)) > 4096: + _refuse( + InsuredUnsupportedReason.UNKNOWN_EARNINGS, + "More than 4096 completions of a flagged prior's first quarter", + ) + for chosen in product(*counts): + credits = dict(upper) + credits.update( + (year, (upper[year][0], count)) + for year, count in zip(open_years, chosen, strict=True) + ) + if any( + _keeps_priors(person, filling, binding, exit_month, **options) + for filling in _placements( + person, credits, sensitive, month, exit_month, lambda c: c + ) + ): + return True + return False + + def _prior_start_binds(person, lower, upper, index, month, exit_month, blind): """Whether annual placement decides a listed prior's start on its basis. @@ -1942,27 +2184,42 @@ def _period_outcomes( yield tuple(found[0][0] for found in witnesses), last, witnesses -def _witness_rank(entry): - """Order a status's witnesses the way ``_witness`` scores them.""" - witness = entry[0] - return witness[0], witness[1] - witness[2], witness[1] +def _witness_rank(entry, disability=False): + """Order a status's witnesses the way ``_witness`` scores them. + + DISABILITY reports its first insured quarter (404.131(a), 404.321(a)), + so an earlier quarter ranks above a larger count. + """ + witness, quarter = entry + first = -_qid(quarter) if disability and witness[0] else 0 + return witness[0], first, witness[1] - witness[2], witness[1] -def _witness_ranks(table): - return [[_witness_rank(entry) for entry in row] for row in table] +def _witness_ranks(table, kinds): + return [ + [_witness_rank(entry, kind is InsuredTest.DISABILITY) for entry in row] + for row, kind in zip(table, kinds, strict=False) + ] -def _keep_favorable(kept, outcomes): +def _keep_favorable(kept, outcomes, kinds): """Each status's best witness so far, for each period ending.""" found = tuple(zip(*(outcome[2] for outcome in outcomes), strict=True)) if kept is None: return found return tuple( tuple( - max(entries, key=_witness_rank) + max( + entries, + key=lambda entry: _witness_rank( + entry, kind is InsuredTest.DISABILITY + ), + ) for entries in zip(*pair, strict=True) ) - for pair in zip(kept, found, strict=True) + for pair, kind in zip( + zip(kept, found, strict=True), kinds, strict=True + ) ) @@ -2056,7 +2313,8 @@ def _settle_first_start( allows. It returns ``(None, ())`` when any filling keeps the start, or when ``reported`` is None because unknown years leave only an envelope. The search holds ``binding`` priors too, so their years count as start - years. + years. When it fails with them and a search without them attains the + result, the refusal names the listed prior's basis as the cause. """ # Source conflict us:oasdi-insured-one-filling-first-start if _start_fixed(person, credits, start, month, exit_month): @@ -2065,7 +2323,12 @@ def _settle_first_start( for quarter in range(_qid(start), _qid(horizon) + 1): try: completed, own_start = _complete_current_period( - person, _qdate(quarter) + person, + _qdate(quarter), + special=_current_period_special( + person, credits, _qdate(quarter), month, exit_month + ) + is not False, ) except InvalidFamilyInput: continue @@ -2087,21 +2350,41 @@ def _settle_first_start( "First insured start depends on annual placement " "or prior treatment", ) - return _settle_fillings( - person, - _fillings_keeping_start( - person, credits, start, month, exit_month, favored, binding - ), - start, - month, - exit_month, - kinds, - returned, - dated=dated, - last_insured=last_insured, - reported=reported, - detail="First insured start depends on annual placement " - "or prior treatment", + detail = ( + "First insured start depends on annual placement or prior treatment" + ) + + def settle(priors): + return _settle_fillings( + person, + _fillings_keeping_start( + person, credits, start, month, exit_month, favored, priors + ), + start, + month, + exit_month, + kinds, + returned, + dated=dated, + last_insured=last_insured, + reported=reported, + detail=detail, + ) + + if not binding: + return settle(()) + try: + return settle(binding) + except InsuredConfigurationUnsupported as error: + if error.detail != detail: + raise + try: + settle(()) + except InsuredConfigurationUnsupported: + raise error from None + _refuse( + InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, + "Annual placement decides a listed prior's first insured quarter", ) @@ -2189,9 +2472,9 @@ def _settle_fillings( if joint is not None and reported is None: return None, () if reported is not None: - kept = _keep_favorable(kept, outcomes) - if joint is not None and _witness_ranks(kept) == _witness_ranks( - reported + kept = _keep_favorable(kept, outcomes, kinds) + if joint is not None and _witness_ranks(kept, kinds) == _witness_ranks( + reported, kinds ): return joint, kept # Every ending must still agree once each keeps the reported start. @@ -2243,6 +2526,61 @@ def _settle_lower_date( ) +def _settle_current_basis( + person, years, low, high, unknown, month, exit_month +): + """Refuse a date last insured the current period's basis decides. + + The period opens 404.130(d) for later quarters only if it rested on + 404.130(c) alone (``_current_period_special``). Where annual placement, + or an UNKNOWN year, decides whether 404.130(b) held in its first quarter, + the date stands only if the two bases give the same one. The flag only + adds a route, so it moves no other result. + """ + start = _qdate(_qid(low[0][0].prior_disability_periods[-1].start)) + found = { + _current_period_special(person, credits, start, month, exit_month) + for _, credits in ((low, high) if unknown else (low,)) + } + if len(found) == 1 and None not in found: + return + for completions, credits in (low, high) if unknown else (low,): + dates = { + tuple( + _last_insured( + replace( + p, + prior_disability_periods=p.prior_disability_periods[ + :-1 + ] + + ( + replace( + p.prior_disability_periods[-1], + special_insured=special, + ), + ), + ), + credits, + month, + exit_month, + years=years, + ) + for p in completions + ) + for special in (False, True) + } + if len(dates) > 1: + _refuse( + ( + InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY + if None in found + else InsuredUnsupportedReason.UNKNOWN_EARNINGS + ), + "Annual placement or an unknown year decides whether the " + "current period rested on 404.130(c) alone", + ) + + def _settle_every_history(person, credits, month, exit_month, decisions, dli): """Refuse a result some annual placement doesn't attain. @@ -2325,11 +2663,12 @@ def _current_period_completions(person, completed, start, month): through = person.current_disability_period_continues_through if through is not None: endings = [end for end in endings if end >= through] + special = completed.prior_disability_periods[-1].special_insured return tuple( replace( completed, prior_disability_periods=person.prior_disability_periods - + (DisabilityPeriod(start, end),), + + (DisabilityPeriod(start, end, special_insured=special),), ) for end in endings ) @@ -2358,14 +2697,12 @@ def _flagged_establishment_possible(person, years): numerical proof. Except for blindness under 404.130(e), they retain the six-QC recent floor by the start horizon, including UNKNOWN prior history. UNKNOWN histories also face the joint optimistic-clock proof. - With known history they additionally need a first insured start clear - of prior quarters, or the automatic pre1956 alternate. A flag's start - is unknown: only ordinary insurance for one filling and treatment - fixes an overlapping first start, including with blindness. The - pre1956 flag adds - no route beyond the automatic alternate (RS00301.480 A/B.1); that - alternate still requires twenty QCs. No flag's own conditions are - adjudicated here. + With known history they additionally need a quarter that meets a + recent rule by the start horizon, or the automatic pre1956 alternate. + A flag's start is unknown, so any such quarter can begin the period. + The pre1956 flag adds no route beyond the automatic alternate + (RS00301.480 A/B.1); that alternate still requires twenty QCs. No + flag's own conditions are adjudicated here. Raw-earnings flags affect compensation or SEI allocation (404.142/.144; RS00301.220/.340/.350). Final direct QC declarations already supply @@ -2423,103 +2760,33 @@ def _minimum_current_period_qcs(person): return min(20, max(6, elapsed // 2)) -def _outside_prior_periods(person, quarter): - """A candidate start must not overlap any declared prior quarter.""" - return all( - not _qid(period.start) <= quarter <= _qid(period.end) - for period in person.prior_disability_periods - ) - - -def _recent_rule_possible( - person, credits, horizon, exit_month, *, lower_credits=None -): +def _recent_rule_possible(person, credits, horizon, exit_month): """404.130(b)-(d) possibility, relaxing only the fully prerequisite. - For one filling and treatment, an overlapping quarter fixes the first - start only if ordinary disability insurance holds without a flag - (404.321(a)). A recent-only witness cannot date a flag's unknown fully - insured status. Blindness has no recent test (404.130(e)). Enumerate - annual placements and unresolved lower fillings, retaining favorable - prior treatment. Complexity cannot disprove a specialist declaration; - this deliberately permits loose refusals rather than losing lawful rows. + A flag supplies fully insured status at an unknown time, so any quarter + from onset through the horizon that meets a recent rule can begin the + period (404.321(a)). Blindness has no recent test (404.130(e)). + Complexity cannot disprove a specialist declaration; this deliberately + permits loose refusals rather than losing lawful rows. """ + if person.statutory_blindness: + return True try: - candidates = range(_qid(person.disability_onset), _qid(horizon) + 1) - if all( - _outside_prior_periods(person, quarter) for quarter in candidates - ): - if person.statutory_blindness: - return True - return any( - _witness( - person, - credits, - _qdate(quarter), - exit_month, - InsuredTest.DISABILITY, - ignore_fully_insured=True, - )[0] - for quarter in candidates - ) - rows, _ = _world(person, credits, _qid(horizon), exit_month, False) - options = [] - for year, row in rows.items(): - high = _assignment_candidates(*row) - if ( - lower_credits is not None - and lower_credits[year] != credits[year] - ): - fixed = tuple(q for q in lower_credits[year][0] if q in row[2]) - vacant = tuple(q for q in row[2] if q not in fixed) - minimum = min(lower_credits[year][1], len(vacant)) - maximum = max(map(len, high)) - len(fixed) - high = tuple( - tuple(sorted((*fixed, *choice))) - for count in range(minimum, maximum + 1) - for choice in combinations(vacant, count) - ) - options.append(high) - if prod(map(len, options)) > 4096: - return True - for choices in product(*options): - filling = { - year: (choice, 0) - for year, choice in zip(rows, choices, strict=True) - } - for treatment in (True, False): - for quarter in range( - _qid(person.disability_onset), _qid(horizon) + 1 - ): - ordinary = _witness( - person, - filling, - _qdate(quarter), - exit_month, - InsuredTest.DISABILITY, - use_periods_only=treatment, - )[0] - # Source conflict us:oasdi-insured-flag-first-insured-quarter - rule_met = ( - person.statutory_blindness - or ordinary - or _witness( - person, - filling, - _qdate(quarter), - exit_month, - InsuredTest.DISABILITY, - ignore_fully_insured=True, - use_periods_only=treatment, - )[0] - ) - if rule_met and _outside_prior_periods(person, quarter): - return True - if ordinary: - break + return any( + _witness( + person, + credits, + _qdate(quarter), + exit_month, + InsuredTest.DISABILITY, + ignore_fully_insured=True, + )[0] + for quarter in range( + _qid(person.disability_onset), _qid(horizon) + 1 + ) + ) except InsuredConfigurationUnsupported: return True - return False def _unknown_prior_joint_shortfall(person, rows, horizon, fully_route): @@ -2529,6 +2796,10 @@ def _unknown_prior_joint_shortfall(person, rows, horizon, fully_route): Allow historical blindness even when current blindness is false. After its earliest possible start, delete every uncredited quarter before the current start while retaining every QC, even interiors. + 404.321(b) and (c) end a period on a month's last day, so a prior + can end in the onset quarter only after an earlier month of it + (RS00301.140 example 7), and only then can 404.130(f) delete an + uncredited onset quarter tested as the start. This relaxation dominates any number of real prior periods, whose endpoints cannot delete credited quarters without also losing QCs. An extra QC cannot hurt either a half-elapsed or a 20/40 test on this @@ -2546,6 +2817,7 @@ def _unknown_prior_joint_shortfall(person, rows, horizon, fully_route): first = max(1937 * 4, _qid(_attain(person.birth_date, 21)) + 1) age31 = _qid(_attain(person.birth_date, 31)) onset = _qid(person.disability_onset) + shared = person.disability_onset.month % 3 != 1 last = _qid(horizon) for choices in product(*options): assigned = {q for annual in choices for q in annual} @@ -2570,14 +2842,15 @@ def clock( earliest=earliest, assigned=assigned, ): - # The candidate itself cannot be excluded. Before the first - # possible prior, every elapsed quarter remains unavoidable. + # A candidate after the onset quarter cannot be excluded. + # Before the first possible prior, every elapsed quarter + # remains unavoidable. return tuple( q for q in range(clock_first, quarter + 1) if earliest is None or q < earliest - or q == quarter + or (q == quarter and not (shared and q == onset)) or q in assigned ) @@ -2621,40 +2894,31 @@ def _could_establish_current_period( maximum_qcs, *, lower_credits=None, - deferred_years=(), totalization_credits=(), ): """Reject only a declaration impossible under every possible route. - A fixed ending or continuity observation bounds the insured start. - Upper credits decide ordinary insurance by that bound, but a derived - prior-quarter overlap must be cleared by that same concrete filling. + A fixed ending or continuity observation bounds the insured start, and + upper credits decide ordinary insurance by that bound, which is + monotone in credited quarters. A period may begin in the quarter a prior + period ended (RS00301.140 example 7), so no start overlaps one. Calendar/schema contradictions have already been rejected. Ordinary premises cannot exclude a specialist route or a short DIB-entitled - prior period. Fixed quarter overlap is checked before searching. - Unresolved prior histories and more than 4096 overlap fillings that - survive that check remain outside the exact ordinary predicate. - The stronger known-history minimum proof stays first. Except for - blindness with a fully-route flag, six QCs must then be feasible by - the immutable horizon before UNKNOWN prior history can preserve a - route. The alternate's start must itself clear prior-period overlap. - UNKNOWN prior histories face an optimistic joint clock that permits - past blindness and dominates every number of real prior periods. - A fully-route flag's starting quarter is unknown. Only ordinary - insurance for one filling and treatment fixes an overlapping first - start, including with blindness (404.321(a)). A construction refusal - preserves possibility until later validation has checked input errors. - A decisive pre1951 aggregate is an automatic fully route, with or - without its flag; it never counts toward the recent rule. + prior period. The stronger known-history minimum proof stays first. + Except for blindness with a fully-route flag, six QCs must then be + feasible by the immutable horizon before UNKNOWN prior history can + preserve a route. UNKNOWN prior histories face an optimistic joint + clock that permits past blindness and dominates every number of real + prior periods. A fully-route flag's starting quarter is unknown, so any + quarter a recent rule meets by the horizon can begin the period + (404.321(a)). A construction refusal preserves possibility until later + validation has checked input errors. A decisive pre1951 aggregate is an + automatic fully route, with or without its flag; it never counts toward + the recent rule. """ if not person.current_disability_period_established: return True horizon = _current_period_start_horizon(person, month) - if person.prior_disability_periods and not any( - _outside_prior_periods(person, quarter) - for quarter in range(_qid(person.disability_onset), _qid(horizon) + 1) - ): - return False # Fixed chronology is independent of the unmodeled foreign route; # no own-credit count proves impossibility on that route here. if totalization_credits: @@ -2677,9 +2941,7 @@ def _could_establish_current_period( person, years, credits, horizon, exit_month ) if fully_route and person.statutory_blindness: - return _recent_rule_possible( - person, credits, horizon, exit_month, lower_credits=lower_credits - ) + return _recent_rule_possible(person, credits, horizon, exit_month) # 404.130(b)-(d) and RS00301.480 retain at least six QCs even # when UNKNOWN prior history changes the window or special route. rows, _ = _world(person, credits, _qid(horizon), exit_month, False) @@ -2702,7 +2964,7 @@ def _could_establish_current_period( ): return True if fully_route and _recent_rule_possible( - person, credits, horizon, exit_month, lower_credits=lower_credits + person, credits, horizon, exit_month ): return True if _pre1956_alternate_possible( @@ -2724,102 +2986,29 @@ def _could_establish_current_period( prior_disability_periods_provenance=EarningsProvenance.OBSERVED, prior_disability_periods_convention_id=None, ) + # Ordinary insurance by a fixed date is monotone in credited quarters, so + # an upper-credit failure disproves every ordinary filling, even if the + # same record first qualifies after the ending. try: _with_current_period(plain, credits, horizon, exit_month) except InsuredConfigurationUnsupported: return True except InvalidFamilyInput: - pass - else: - return True - # Ordinary insurance by a fixed date is monotone in credited quarters. - # An upper-credit failure here therefore disproves every ordinary - # filling, even if the same record first qualifies after the ending. - if not _decision_witness( - plain, credits, horizon, exit_month, InsuredTest.DISABILITY - )[0][0]: return False - unknown = tuple( - year - for year, row in sorted(years.items()) - if ( - row.provenance is EarningsProvenance.UNKNOWN - or year in deferred_years - ) - and year <= horizon.year - ) - if not unknown: - return False - lower = dict(credits if lower_credits is None else lower_credits) - if lower_credits is None: - lower.update({year: ((), 0) for year in unknown}) - try: - _with_current_period(plain, lower, horizon, exit_month) - except InsuredConfigurationUnsupported: - return True - except InvalidFamilyInput: - pass - else: - return True - # A later witness alone does not suffice: the first insured quarter - # must both avoid the represented prior period and precede the fixed - # bound. Enumerate complete fillings only in this nonmonotone corner. - options = [] - for year in unknown: - allowed = rows.get(year, ((), 0, ()))[2] - if year < 1978: - fixed = tuple(q for q in lower[year][0] if q in allowed) - vacant = tuple(q for q in allowed if q not in fixed) - options.append( - tuple( - ( - tuple( - sorted( - fixed - + tuple( - q - for q, flag in zip( - vacant, flags, strict=True - ) - if flag - ) - ) - ), - 0, - ) - for flags in product((False, True), repeat=len(vacant)) - ) - ) - else: - options.append( - tuple( - ((), count) - for count in range(min(len(allowed), credits[year][1]) + 1) - ) - ) - if prod(map(len, options)) > 4096: - _refuse( - InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, - "More than 4096 current-period overlap fillings; " - "ordinary establishment validity is unresolved", - ) - for choices in product(*options): - filling = dict(credits) - filling.update(zip(unknown, choices, strict=True)) - try: - _with_current_period(plain, filling, horizon, exit_month) - except InsuredConfigurationUnsupported: - return True - except InvalidFamilyInput: - continue - return True - return False + return True -def _status_decision(lo_candidates, hi_candidates, envelope=None): - """One status from its candidates; ``envelope`` widens unsure counts.""" +def _status_decision( + lo_candidates, hi_candidates, envelope=None, earliest=None +): + """One status from its candidates; ``envelope`` widens unsure counts. + + ``earliest`` widens an insured status's upper qualifying quarter. + """ lo, lo_quarter = lo_candidates[-1] hi, hi_quarter = hi_candidates[0] + if earliest is not None and hi[0]: + hi_quarter = earliest witnesses = [value for value, _ in (*lo_candidates, *hi_candidates)] count_lo, count_hi, full_lo, full_hi = ( (0, envelope, 0, envelope) @@ -2908,20 +3097,18 @@ def insured_status( six-QC floor uses credits feasible by the immutable start horizon; only blindness with a fully-route flag bypasses it. UNKNOWN prior history changes windows or special eligibility, never this floor. - With known nonblind history, fully-route flags must retain a recent - first insured start outside prior quarters, or automatic pre1956 + With known nonblind history, fully-route flags must retain a quarter + meeting a recent rule by the start horizon, or automatic pre1956 alternate. A pre1951 aggregate that could supply a failed fully insured prerequisite is such a route without a flag, and DISABILITY, the start and the date last insured refuse by name when it decides them. UNKNOWN history also faces a joint optimistic-clock proof permitting past blindness; survival never claims a concrete history. - A fully-route flag's start is unknown, including with blindness; - only ordinary insurance for the same filling and treatment fixes an - overlapping first quarter. The alternate must use one - start clearing fixed overlap, the horizon and its 1955 date limit; - its prior-period clock and credited endpoints remain unchanged. - If a clear first start depends on annual placement or prior treatment - after a favorable overlapping start, retain a named boundary refusal. + A fully-route flag's start is unknown, including with blindness. A + period may begin in the quarter a prior period ended (RS00301.140 + example 7). The alternate must use one start within the horizon and its + 1955 date limit; its prior-period clock and credited endpoints remain + unchanged. A first successful filling cannot settle the other requested statuses: wherever placement or treatment can move the start, one filling with its own start must attain the returned result and none may beat it. @@ -2975,7 +3162,6 @@ def insured_status( coverage_end_month, maximum_qcs, lower_credits=lower, - deferred_years=tuple(deferred), totalization_credits=totalization_credits, ) except InsuredConfigurationUnsupported: @@ -2983,6 +3169,16 @@ def insured_status( raise next(iter(deferred.values())) from None raise if not possible: + try: + _refuse_unsupported_priors( + person, lower, upper, month, coverage_end_month + ) + except InsuredConfigurationUnsupported: + # A deferred row keeps its own reason, as it does once a + # possible declaration survives. + if deferred: + raise next(iter(deferred.values())) from None + raise raise InvalidFamilyInput( "Established current period has no possible insured disabled quarter" ) @@ -3048,6 +3244,9 @@ def insured_status( ) except InvalidFamilyInput: if unknown: + _refuse_unsupported_priors( + person, lower, upper, month, coverage_end_month + ) _refuse( InsuredUnsupportedReason.UNKNOWN_EARNINGS, "Unknown earnings decide a valid established current period", @@ -3220,8 +3419,21 @@ def insured_status( ) ) candidates[kind] = lo_candidates + # An UNKNOWN prior can set quarters aside and reach earlier QCs, so the + # first insured quarter can fall as early as onset (404.130(f), + # 404.131(a)). The proof below shows it falls no later. + earliest = ( + _qdate(_qid(person.disability_onset)) + if kind is InsuredTest.DISABILITY + and prior_unknown + and person.disability_onset is not None + else None + ) decisions[kind] = _status_decision( - lo_candidates, hi_candidates, maximum_qcs if broad else None + lo_candidates, + hi_candidates, + maximum_qcs if broad else None, + earliest=earliest, ) dli = None if test in (InsuredTest.ALL, InsuredTest.DISABILITY): @@ -3252,6 +3464,16 @@ def insured_status( # false current status cannot prove a positive DLI lower date. lo_date = None dli = _computed(DLIRange, lo_date, hi_date, lo_censored or hi_censored) + if lo_start is not None and not prior_unknown: + _settle_current_basis( + person, + years, + (lo_completions, lower), + (hi_completions, upper), + bool(unknown), + month, + coverage_end_month, + ) if prior_unknown or current_unknown: _settle_every_history( person, lower, month, coverage_end_month, decisions, dli @@ -3265,7 +3487,8 @@ def insured_status( binding = tuple( (index, blind) for index, blind in enumerate(bases) - if not current_unknown + if blind is not None + and not current_unknown and _prior_start_binds( person, lower, upper, index, month, coverage_end_month, blind ) @@ -3275,7 +3498,7 @@ def insured_status( InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, "Annual placement decides a listed prior's first insured quarter", ) - placement = None + placement, basis_split = None, False if lo_start is not None or binding: favored_rows, _ = _world( lo_person, @@ -3331,8 +3554,42 @@ def insured_status( **search, ) ) - for kind, witnesses in zip(kinds, settled, strict=False): - decisions[kind] = _status_decision(witnesses, witnesses) + # The record doesn't say whether an unflagged prior rested on past + # blindness (404.130(e)), so each status reports the range the two + # bases give where they differ (round 21; RS00301.150 A). + lenient = tuple( + (index, blind or _blind_basis(person, index)) + for index, blind in binding + ) + loose = settled + if settled and lenient != binding: + _, loose = ( + _settle_first_start( + person, + upper, + hi_start, + month, + coverage_end_month, + kinds, + returned, + **{**search, "binding": lenient}, + ) + if lo_start is not None + else _settle_listed_priors( + person, + upper, + month, + coverage_end_month, + kinds, + returned, + **{**search, "binding": lenient}, + ) + ) + basis_split = _witness_ranks(loose, kinds) != _witness_ranks( + settled, kinds + ) + for kind, strict, wide in zip(kinds, settled, loose, strict=False): + decisions[kind] = _status_decision(strict, wide) if lo_start is not None and dli is not None and dli.lower is not None: _settle_lower_date( person, @@ -3382,6 +3639,7 @@ def insured_status( ("prior_disability_periods", prior_unknown), ("current_disability_period", current_unknown), ("current_disability_period_start", uncertain_current_start), + ("prior_disability_period_basis", basis_split), ("current_disability_period_end", end_unknown), ("sspa211_applicability", applicability is None), ) diff --git a/tests/README-tiers.md b/tests/README-tiers.md index 5a152b6eb..a3d8abbcf 100644 --- a/tests/README-tiers.md +++ b/tests/README-tiers.md @@ -39,7 +39,7 @@ pytest --collect-only -q -m oracle_policyengine | tail -1 | Tier | Tests at HEAD | |---|---:| -| `unit` | 25,445 | +| `unit` | 25,525 | | `artifact` | 4,271 | | `integration_psid` | 1,471 | | `reproduction_legacy` | 520 | diff --git a/tests/data/track_b/insured_status_examples.yaml b/tests/data/track_b/insured_status_examples.yaml index 86812715b..4116d8730 100644 --- a/tests/data/track_b/insured_status_examples.yaml +++ b/tests/data/track_b/insured_status_examples.yaml @@ -194,15 +194,22 @@ examples: second_required: 9 insured: true coverage: source_rule_divergence - note: Published 18-quarter/9-QC requirement excludes both qualifying endpoint - quarters; statutory endpoint counting yields 20/10. Both answers insure the - record. Kept side by side for review. + note: The printed 18 quarters exclude both endpoint quarters of the prior + period. 404.130(f) counts an endpoint quarter that is a QC, and on the + printed placement only 1981Q1 is one, so 19 quarters reduce to 18 and 9 + QCs, the printed requirement. The rule also assigns a 1982 QC to the 1982Q4 + endpoint, giving 20/10. RS 00301.140 assigns a post-1977 QC to any quarter + of its year if insured status would be met, and both placements insure, so + the printed figures are placement-dependent intermediate counts, not an + erratum. The + first onset's 14 quarters and 7 QCs reproduce; the first record holds 9 QCs + there, of which the example says Joseph requires and has 7. implemented: elapsed_quarters: 20 required_qcs: 10 available_qcs: 16 insured: true - test_node: tests/test_track_b_insured_status.py::test_joseph_subsequent_poms_140_example_6_endpoint_erratum + test_node: tests/test_track_b_insured_status.py::test_joseph_subsequent_poms_140_example_6_endpoint_placement - id: poms_140_jane source: poms_rs_00301_140 quotes: @@ -285,6 +292,9 @@ examples: insured: true coverage: computed test_node: tests/test_track_b_insured_status.py::test_subsequent_over31_poms_147_examples + note: The source says Mary had 8 QC's in the first onset's 16 quarters, but + its own pattern holds 9 there (1971Q3-Q4, 1972Q1-Q3, 1973Q1 and Q4, + 1974Q3-Q4). The requirement of 8 and the insured disposition reproduce. - id: poms_147_john source: poms_rs_00301_147 quotes: @@ -329,8 +339,11 @@ examples: observed_qcs: 8 insured: false coverage: source_rule_divergence - note: Published 33/16/8 treats 1978 annual QC as fixed Q1. Favorable reassignment - to PPD endpoint1978Q4 yields34/17/9; both deny insured status. + note: Published 33/16/8 keeps the 1978 QC in 1978Q1, outside the prior + period's 1978Q4 endpoint. Assigning it to that endpoint gives 34/17/9. + RS 00301.140 assigns a post-1977 QC to any quarter of its year if insured + status would be met, and neither placement insures, so the printed figures + are placement-dependent intermediate counts, not an erratum. test_node: tests/test_track_b_insured_status.py::test_subsequent_over31_poms_147_examples implemented: elapsed_quarters: 34 @@ -579,7 +592,7 @@ examples: coverage: source_ambiguity note: The capture labels10900 as SEI but prints3600 for each of3 quarters. Literal already-covered SEI gives10900/3. An unstated10800 ceiling for TYbeginning1973, - from RS00301.345 and Act213(a)(2)(B)(iii), explains3600 each if10900 meant net + from RS00301.345 B.2.g and its example C.1, explains3600 each if10900 meant net earnings before the ceiling. Both readings are executed; neither an arithmetic erratum nor the omitted ceiling is established by the capture. Both yield3QCs and differ by100 in allocated earnings. Private helper consumes already-covered @@ -743,8 +756,12 @@ examples: test_node: tests/test_track_b_insured_status.py::test_fully_requirement_differential_poms_rs_00301_800_exhibit note: Text extracted from the exhibit PDF (pdftotext), with the PDF and both GIF renderings pinned in served_bodies. Every row is checked by birth cohort, - by the January 1 footnote and by year of death. The PDF's footnote misprints - the male age-65 cohort as 1/2/31; the GIF and 20 CFR 404.132(b) say 1913. + by the January 1 footnote and by year of death. The PDF's footnote 2 gives + age 65 to men born before 1/2/31; 404.110(b)(2)(iv) gives it only to a man + who reached 62 before 1973, and (iii) ends the count before 1975 for one + born from January 2, 1911 through January 1, 1913. (ii) covers the rest of + 1913, and together they give the merged 1910-1913 row. The GIF text is not + captured. - id: poms_102_1_lucinda source: poms_rs_00301_102 quotes: diff --git a/tests/data/track_b/insured_status_sources/README.md b/tests/data/track_b/insured_status_sources/README.md index df89d631f..47757d287 100644 --- a/tests/data/track_b/insured_status_sources/README.md +++ b/tests/data/track_b/insured_status_sources/README.md @@ -10,9 +10,12 @@ retain the exact transmittal and page date. The staging log was removed only after all original byte counts and hashes were verified. The source tests recompute every retained capture's hash and verify a specific rule or documentary-purpose quote from every capture. The example registry at -`../insured_status_examples.yaml` checks every published figure against -its source and distinguishes computations, refusals, errata and unavailable -attachments. +`../insured_status_examples.yaml` distinguishes computations, refusals, +errata and unavailable attachments. The source tests check that each of +its quotes appears in the capture and that each entry the rule executes +names an existing test; that test asserts the figures it computes. The +`expected` and `implemented` fields record the source's and the rule's +figures for review, and no test reads them. The capture formats follow the gross-benefit manifest, with one addition: @@ -63,18 +66,24 @@ OACT agree on all 49 shared years, including POMS's joint 2010-2011 row. RS 00301.800 links to two GIF images and one PDF of its exhibit. The PDF's text is captured as `pdf_text`, and all three bodies are pinned by hash. Every exhibit row is compared, as is every row of CFR 404.115's cohort -chart. The PDF's footnote misprints the male age-65 cohort as "born before -1/2/31"; the GIF rendering, the exhibit's own table and 20 CFR 404.132(b) -say January 2, 1913. RS 00301.149 only points to the SSA-1164 worksheet; -no worksheet reproduction is claimed. +chart. The PDF's footnote 2 gives age 65 to "men born before 1/2/31". +20 CFR 404.110(b)(2)(iv) gives it only to a man who became 62 before 1973, +born before January 2, 1911, and (iii) ends the count before 1975 for one +born from then through January 1, 1913. (ii) covers the rest of 1913, and +together they give the exhibit's merged 1910-1913 row. The January 2, 1913 +date in 20 CFR 404.132(b) belongs to the disability prerequisite's 1975 +cap. The GIF renderings are pinned by hash only, and their text is not +captured. RS 00301.149 only points to the SSA-1164 worksheet; no worksheet +reproduction is claimed. RS 00301.340's short-year example states $10,900 of self-employment income but allocates $3,600 to each of three quarters, totaling $10,800. There are two readings. Taking the amount literally as already covered SEI gives $10,900 / 3 per quarter. An unstated contribution-base ceiling could explain the printed allocation if $10,900 instead means net -earnings before the ceiling: RS 00301.345 and Act 213(a)(2)(B)(iii) identify -$10,800 for a taxable year beginning in 1973, and $10,800 / 3 = $3,600. +earnings before the ceiling: RS 00301.345 B.2.g gives $10,800 for a taxable +year beginning in 1973, its example C.1 counts only $8,100 of $10,600 of net +earnings as SEI beside $2,700 of wages, and $10,800 / 3 = $3,600. The tests execute both readings. The capture does not state that ceiling step, so this is an unresolved source assumption rather than a proven arithmetic erratum. Both readings give three QCs; the allocated earnings diff --git a/tests/test_track_b_insured_status.py b/tests/test_track_b_insured_status.py index e974ffee4..c41399a17 100644 --- a/tests/test_track_b_insured_status.py +++ b/tests/test_track_b_insured_status.py @@ -271,10 +271,12 @@ def _rs00301_800_exhibit_rows(): def test_fully_requirement_differential_poms_rs_00301_800_exhibit(): """Every row of the RS 00301.800 exhibit, by birth cohort and death year. - Men born before January 2, 1913 use age 65 and women age 62; from 1914 - one row serves both. Footnote 1: a January 1 birth takes the prior - year's row. The death-year column is checked for a worker who attained - 21 before 1951 (born July 1, 1929) and dies that year. + A man born before January 2, 1911 counts to age 65, one born from then + through January 1, 1913 to 1975 (404.110(b)(2)(iii)-(iv)), and a woman + to 62; from 1914 one row serves both. Footnote 1: a January 1 birth + takes the prior year's row. The death-year column is checked for a + worker who attained 21 before 1951 (born July 1, 1929) and dies that + year. The age below only picks a query month after the count ends. """ tested = 0 for men, women, event, required in _rs00301_800_exhibit_rows(): @@ -824,7 +826,10 @@ def test_property_disability_period_exclusion_never_adds_qcs( ) -def test_unknown_upper_bound_respects_exit_quarter(): +def test_unknown_exit_year_keeps_every_quarter_of_its_year(): + """RS00301.230 B places an annual QC in any quarter of its year, and + RS00301.240 bars no quarter for an exit, so the exit bars later years + only and an UNKNOWN exit year can reach four QCs.""" person = i.Person( date(2000, 2, 2), prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, @@ -843,7 +848,7 @@ def test_unknown_upper_bound_respects_exit_quarter(): coverage_end_month=exit_month, test=i.InsuredTest.FULLY, ) - assert result.qcs_by_year[2026] == (0, 2) + assert result.qcs_by_year[2026] == (0, 4) assert result.fully.insured @@ -865,7 +870,7 @@ def test_special_insured_quarter_before_31_boundary(): assert not attainment_quarter.disability.insured -def test_joseph_subsequent_poms_140_example_6_endpoint_erratum(): +def test_joseph_subsequent_poms_140_example_6_endpoint_placement(): person = i.Person( date(1956, 9, 16), disability_onset=date(1984, 2, 14), @@ -886,8 +891,11 @@ def test_joseph_subsequent_poms_140_example_6_endpoint_erratum(): {1978: 2, 1979: 3, 1980: 4, 1981: 1, 1982: 2, 1983: 4, 1984: 1}, ) assert result.disability.insured - # The capture says 18 elapsed / 9 needed. Under .240 and 404.130(f), - # its credited first/last quarters remain: 26 total - 6 interior =20. + # The capture says 18 elapsed / 9 needed, excluding both endpoint + # quarters. Under .240 and 404.130(f) an endpoint quarter counts where it + # is a QC. The printed placement credits only 1981Q1, so 19 reduce to the + # printed 18 and 9; assigning a 1982 QC to 1982Q4 credits both, so the + # 26 quarters less 6 interior ones leave 20 and 10. Both insure. source_elapsed, source_required = 18, 9 assert len(result.disability.window) == source_elapsed + 2 == 20 assert result.disability.required == source_required + 1 == 10 @@ -1181,7 +1189,7 @@ def test_guinness_lis_poms_120_freeze_protects_onset_status(): ids=[ "mary-brown-example-1", "john-jones-example-2", - "frank-smith-example-3-moveable-qc-erratum", + "frank-smith-example-3-moveable-qc-placement", ], ) def test_subsequent_over31_poms_147_examples( @@ -1214,8 +1222,9 @@ def test_subsequent_over31_poms_147_examples( assert len(result.disability.window) == elapsed assert result.disability.rule == "subsequent_special" if birth == date(1945, 7, 14): - # Source freezes 1978 CNNN in Q1. .230 permits moving it to Q4, - # the last PPD quarter; .240 then retains it in both counts. + # Source keeps 1978 CNNN in Q1. .230 permits moving it to Q4, the + # last PPD quarter, and .240 then retains it in both counts; neither + # placement insures. source_elapsed, source_required, source_available = 33, 16, 8 assert elapsed == source_elapsed + 1 assert required == source_required + 1 diff --git a/tests/test_track_b_insured_status_classification_oracle.py b/tests/test_track_b_insured_status_classification_oracle.py index 1976115cc..7f76136dd 100644 --- a/tests/test_track_b_insured_status_classification_oracle.py +++ b/tests/test_track_b_insured_status_classification_oracle.py @@ -10,8 +10,14 @@ two UNKNOWN credit years (each completed by every permitted quarter subset, up to sixteen), two observed prior periods, and bounded UNKNOWN histories. UNKNOWN history is completed by the empty history and every one-period quarter interval -from the first possible credited quarter through the onset quarter, with the -end clamped before the onset day. Each start must itself be insured. Special +from the first possible credited quarter through the onset quarter, ending on +the quarter's last month end before the onset day (404.321(b), (c) end every +period on a month's last day). Each start must itself be insured. A +period begins on the onset day or on the first day of a later insured +quarter (404.321(a)), so it may share a quarter with the end of the prior +before it (RS 00301.140 example 7). Annual QCs take any begun quarter of +their year through death (RS 00301.230 B, RS 00301.240); neither the birth +quarter nor the exit bars a quarter of its own year. Special provenance is admitted only for an under31 witness without 20/40. Earlier blindness may supply insurance through fully insured status even when current blindness is absent. Two bounded classes combine a blind prefix with a later @@ -41,9 +47,17 @@ Declarations use female sex; the male fully insured transition for cohorts born before 1913 is outside the bound. The separate round 13 regression module covers credit-adding routes. Known prior -periods are declared established facts and are not re-adjudicated. This oracle -checks declaration classification, not coherence across separate assignment -witnesses returned for individual statuses and DLI. +periods are declared established facts. The oracle asks only whether some +completion begins each one on a route its flag allows: a flagged prior on the +under-31 route without 20 of 40 (404.130(d)(1)); an unflagged one on 20 of 40, +on the subsequent route after a flagged prior, on fully insured status alone +from January 1973 (past blindness, 404.130(e), RS 00301.150 A), or on RS +00301.480 B.1 where no completion has 20 of 40 through September 1960. A +fully-route flag may supply fully insured status before any prior. Where no +completion supports a listed prior, the record omits facts and keeps a row +refused by name, whether or not a filling insures the current period. This +oracle checks declaration classification, not coherence across separate +assignment witnesses returned for individual statuses and DLI. """ from __future__ import annotations @@ -130,6 +144,15 @@ class EnumeratedPeriod: special_insured: bool = False +@dataclass(frozen=True) +class _Holder: + """The person facts the route checks read, blind or not.""" + + birth_date: date + death_date: date | None + statutory_blindness: bool + + @dataclass(frozen=True) class Declaration: person: rule.Person @@ -225,15 +248,10 @@ def _placements(case): last = min( _quarter(case.month), _quarter(person.death_date) if person.death_date else 99999, - _quarter(case.exit_month) if case.exit_month else 99999, ) alternatives = [] for year, fixed, count in case.annual: - slots = tuple( - q - for q in range(year * 4, year * 4 + 4) - if _quarter(person.birth_date) <= q <= last - ) + slots = tuple(q for q in range(year * 4, year * 4 + 4) if q <= last) if fixed is not None: alternatives.append((fixed,)) elif count is None: @@ -424,6 +442,94 @@ def _alternate(case, credits, start, periods, prior): return len(used) >= 20 and len(continuous) >= 6 and set(continuous) <= used +@lru_cache(maxsize=16384) +def _unsupported_prior(case): + """Whether no completion begins some listed prior on its route.""" + person = case.person + fully_from = ( + _quarter(person.birth_date) - 1 + if set(person.conditions) & set(FULLY_FLAGS) + else None + ) + placements = tuple(_placements(case)) + for index, period in enumerate(person.prior_disability_periods): + if any( + _prior_begins(person, credits, index, fully_from) + for credits in placements + ): + continue + earlier = tuple(person.prior_disability_periods[:index]) + if not period.special_insured and _alternate_prior( + placements, _quarter(period.start), earlier + ): + continue + return True + return False + + +def _prior_begins(person, credits, index, fully_from): + """Whether one placement begins a listed prior on a route it allows.""" + period = person.prior_disability_periods[index] + earlier = tuple(person.prior_disability_periods[:index]) + treatments = (earlier, ()) if earlier else ((),) + ordinary, blind = ( + [ + _ordinary_routes( + _Holder(person.birth_date, person.death_date, holder_blind), + credits, + _quarter(period.start), + treatment, + fully_from, + special=any(p.special_insured for p in earlier), + ) + for treatment in treatments + ] + for holder_blind in (False, True) + ) + if period.special_insured: + # 404.130(f) disregards favorably, so 20 of 40 under either + # treatment means the holder was not "only" insured under (c). + return any("under31" in r for r in ordinary) and not any( + "20_of_40" in r for r in ordinary + ) + return any( + "20_of_40" in r or "subsequent_special" in r for r in ordinary + ) or (period.start >= date(1973, 1, 1) and any(blind)) + + +def _alternate_prior(placements, start, earlier): + """RS 00301.480 B.1 counts on every completion and A's 20 of 40 on none.""" + if not 1952 * 4 + 2 <= start <= 1955 * 4 + 3: + return False + treatments = (earlier, ()) if earlier else ((),) + for credits in placements: + used = _usable(credits, start, earlier) + continuous = _elapsed_quarters(1951 * 4, start - 1, earlier, used) + if not ( + len(used) >= 20 + and len(continuous) >= 6 + and set(continuous) <= used + ): + return False + for candidate in range(start, 1960 * 4 + 3): + for treatment in treatments: + used = _usable(credits, candidate, treatment) + window = _lookback(candidate, 40, treatment, used) + if len(used & window) >= 20: + return False + return True + + +def _prior_end(last, onset): + """The last month end of quarter ``last`` before the onset day.""" + end = _month_end( + _quarter_date(last).replace(month=_quarter_date(last).month + 2) + ) + while end >= onset: + end = end.replace(day=1) - timedelta(days=1) + return end if _quarter(end) == last else None + + def _unknown_priors(case, credits, fully_from): person = case.person yield () @@ -448,26 +554,16 @@ def _unknown_priors(case, credits, fully_from): for last in range(first, stop + 1): # At quarter resolution a one-month DIB-entitled period can # occupy even a single quarter (Act216(i)(2)(A),404.315(a)(4)). - end = min( - _month_end( - _quarter_date(last).replace( - month=(_quarter_date(last).month + 2) - ) - ), - person.disability_onset - timedelta(days=1), - ) + end = _prior_end(last, person.disability_onset) + start = max(person.birth_date, _quarter_date(first)) + if end is None or end < start: + continue for special in ( (False, True) if "under31" in routes and "20_of_40" not in routes else (False,) ): - yield ( - EnumeratedPeriod( - max(person.birth_date, _quarter_date(first)), - end, - special_insured=special, - ), - ) + yield (EnumeratedPeriod(start, end, special_insured=special),) special_stop = min(stop, _quarter(_attained(person.birth_date, 31)) - 1) # Preserve the existing favorable birth prefix. Its gap before the later @@ -509,14 +605,9 @@ def _special_after_prefix(case, credits, fully_from, prefix, first): if "under31" not in routes or "20_of_40" in routes: return for last in range(first, _quarter(person.disability_onset) + 1): - end = min( - _month_end( - _quarter_date(last).replace( - month=(_quarter_date(last).month + 2) - ) - ), - person.disability_onset - timedelta(days=1), - ) + end = _prior_end(last, person.disability_onset) + if end is None: + continue yield ( prefix, EnumeratedPeriod(_quarter_date(first), end, special_insured=True), @@ -587,49 +678,29 @@ def _enumerated_filling(case): else (person.prior_disability_periods,) ) for prior in histories: - if _history_has_clear_start( + if _history_has_insured_start( case, credits, prior, horizon, fully_from ): return True return False -def _history_has_clear_start(case, credits, prior, horizon, fully_from): +def _history_has_insured_start(case, credits, prior, horizon, fully_from): person = case.person starts = range( _quarter(person.disability_onset), horizon + 1, ) + special = any(p.special_insured for p in prior) for periods in ((prior, ()) if prior else ((),)): - # 404.321(a) fixes the first insured quarter. A later - # clear quarter cannot repair an already insured but - # overlapping onset quarter for this fixed filling, treatment and f. - first_ordinary = next( - ( - start - for start in starts - if _ordinary_routes( - person, - credits, - start, - periods, - fully_from, - special=any(p.special_insured for p in prior), - ) - ), - None, - ) - if first_ordinary is not None and not any( - _quarter(p.start) <= first_ordinary <= _quarter(p.end) - for p in prior - ): - return True + # 404.321(a) starts the period on the onset day, or on the first + # day of the first insured quarter after it. Either day follows + # every prior's end, even in that prior's last quarter + # (RS00301.140 example 7), so any insured start is lawful. for start in starts: - if any( - _quarter(p.start) <= start <= _quarter(p.end) for p in prior - ): - continue - if _alternate(case, credits, start, periods, prior): + if _ordinary_routes( + person, credits, start, periods, fully_from, special=special + ) or _alternate(case, credits, start, periods, prior): return True return False @@ -657,20 +728,26 @@ def _public_rows(case): def _check_classification(case): possible = _has_valid_filling(case) + unsupported = _unsupported_prior(case) + kept = possible or unsupported rows = _public_rows(case) if not rows: assert not possible, f"oracle found a concrete filling: {case!r}" + assert not unsupported, f"oracle found an unsupported prior: {case!r}" else: - assert possible, f"oracle found no valid filling: {case!r}" + assert kept, f"oracle found no valid filling: {case!r}" row = rows[0] assert (row.result is None) != (row.unsupported is None) if row.unsupported is not None: assert isinstance( row.unsupported.reason, rule.InsuredUnsupportedReason ) + assert ( + row.unsupported is not None or not unsupported + ), f"an unsupported prior computed: {case!r}" counts = count_family_outcomes(rows) - assert counts.rows == int(possible) - assert counts.weight == WEIGHT * int(possible) + assert counts.rows == int(kept) + assert counts.weight == WEIGHT * int(kept) assert counts.unsupported_rows == sum( row.unsupported is not None for row in rows ) @@ -1071,8 +1148,9 @@ def test_classification_oracle_onset_quarter_and_credited_endpoint(flags): (1962 * 4, 1962 * 4 + 1, 1962 * 4 + 2), (5, 6, 19, 20), ): - # A credited prior endpoint remains in the window, while an - # established current start still cannot occupy that quarter. + # A credited prior endpoint remains in the window, and an + # established current start may begin in that quarter after the + # prior's last day (RS00301.140 example 7). fixed = (*range(1957 * 4, 1957 * 4 + total - 1), credit_quarter) _check_classification( _declaration( @@ -1202,7 +1280,8 @@ def test_classification_oracle_unknown_history_cannot_remove_six_qc_floor( _check_classification(case) -def test_classification_oracle_alternate_needs_clear_start_before_1956(): +def test_classification_oracle_alternate_can_start_in_a_prior_end_quarter(): + """The 1955Q4 alternate start follows the prior's November end.""" case = _declaration( birth=date(1900, 2, 2), onset=date(1955, 12, 15), @@ -1211,12 +1290,45 @@ def test_classification_oracle_alternate_needs_clear_start_before_1956(): periods=(rule.DisabilityPeriod(date(1952, 7, 1), date(1955, 11, 30)),), fixed=(*range(1938 * 4, 1941 * 4 + 2), *range(1951 * 4, 1952 * 4 + 2)), ) + assert _has_valid_filling(case) + _check_classification(case) + + +@pytest.mark.parametrize("flagged", (False, True)) +def test_classification_oracle_fully_flag_can_carry_a_listed_prior(flagged): + """A flag's fully insured status can begin a prior its counts can't. + + Twenty QCs in 1962-1967 hold 20 of 40 at the 1972 prior's start, short + of the 21 elapsed years fully insured status needs, and age out of the + window by the 1974 onset. Without a flag no completion begins the + prior, so the row refuses by name; a flag can carry it, and the current + period then has no insured quarter. + """ + case = _declaration( + birth=date(1910, 2, 2), + onset=date(1974, 12, 15), + end=date(1975, 1, 31), + month=date(1975, 2, 1), + flags=(FULLY_FLAGS[0],) if flagged else (), + periods=(rule.DisabilityPeriod(date(1972, 1, 1), date(1972, 3, 31)),), + fixed=tuple(range(1962 * 4 + 1, 1967 * 4 + 1)), + ) assert not _has_valid_filling(case) + assert _unsupported_prior(case) is not flagged _check_classification(case) + rows = _public_rows(case) + if flagged: + assert rows == () + else: + assert ( + rows[0].unsupported.reason + is rule.InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY + ) @pytest.mark.parametrize("flag", FULLY_FLAGS) -def test_classification_oracle_fully_flag_cannot_delay_an_insured_onset(flag): +def test_classification_oracle_fully_flag_keeps_an_insured_onset(flag): + """An onset insured in a prior's end quarter starts on its day.""" case = _declaration( birth=date(1910, 2, 2), onset=date(1962, 2, 15), @@ -1226,7 +1338,7 @@ def test_classification_oracle_fully_flag_cannot_delay_an_insured_onset(flag): periods=(rule.DisabilityPeriod(date(1960, 1, 1), date(1962, 1, 31)),), fixed=(*range(1957 * 4, 1961 * 4 + 3), 1962 * 4), ) - assert not _has_valid_filling(case) + assert _has_valid_filling(case) _check_classification(case) @@ -1259,8 +1371,8 @@ def test_classification_oracle_blind_fully_flag_still_has_one_first_start( @pytest.mark.parametrize("flag", FULLY_FLAGS) -def test_classification_oracle_blind_ordinary_onset_cannot_be_delayed(flag): - """Ordinary fully insurance fixes this overlapping start for every f.""" +def test_classification_oracle_blind_ordinary_onset_starts_after_prior(flag): + """Ordinary fully insurance starts the period the day after a prior.""" case = _declaration( birth=date(1960, 2, 2), flags=(flag,), @@ -1268,10 +1380,11 @@ def test_classification_oracle_blind_ordinary_onset_cannot_be_delayed(flag): periods=(rule.DisabilityPeriod(date(1999, 1, 1), date(2000, 1, 14)),), counts=tuple((year, 4) for year in range(1980, 1990)), ) - assert not _has_valid_filling(case) - with pytest.raises(rule.InvalidFamilyInput): - rule.insured_status(case.person, _history(case), case.month) + assert _has_valid_filling(case) _check_classification(case) + unflagged = replace(case.person, conditions=frozenset()) + result = rule.insured_status(unflagged, _history(case), case.month) + assert result.current_disability_period_start == date(2000, 1, 15) @pytest.mark.parametrize("two_priors", (False, True)) @@ -1300,7 +1413,7 @@ def test_classification_oracle_no_flag_historical_blind_prior(two_priors): @pytest.mark.parametrize("flag", FULLY_FLAGS) def test_classification_oracle_free_flag_start_preserves_disregard(flag): - """A recent-only overlapping quarter is not an insured first start.""" + """A recent-only quarter is not an insured first start.""" case = _declaration( birth=date(1924, 1, 2), onset=date(1985, 2, 15), diff --git a/tests/test_track_b_insured_status_contract.py b/tests/test_track_b_insured_status_contract.py index 556569ca6..01ee1a224 100644 --- a/tests/test_track_b_insured_status_contract.py +++ b/tests/test_track_b_insured_status_contract.py @@ -60,8 +60,10 @@ def test_currently_insured_uses_death_quarter_after_death(): "field", ["rib_entitlement_month", "dib_entitlement_month"] ) def test_currently_insured_preserves_actual_entitlement_event(field): + # RIB entitlement needs age 62 (Act 202(a)(2)), which a holder born in + # January 1958 reaches in 2020. person = i.Person( - date(1960, 1, 2), + date(1958, 1, 2), **{field: date(2020, 12, 1)}, prior_disability_periods_provenance=i.EarningsProvenance.OBSERVED, current_disability_period_established=False, diff --git a/tests/test_track_b_insured_status_fix_round_10.py b/tests/test_track_b_insured_status_fix_round_10.py index 7baf9cfbf..30dea41ce 100644 --- a/tests/test_track_b_insured_status_fix_round_10.py +++ b/tests/test_track_b_insured_status_fix_round_10.py @@ -319,7 +319,15 @@ def test_continuous_alternate_clock_requires_each_of_twenty_qcs(deleted): flags = list(years[year].qc_quarters) flags[quarter] = False years[year] = i.CoverageYear(OBSERVED, qc_quarters=tuple(flags)) - _assert_invalid(lambda: _row(person, years, month)) + # The listed prior began on the same clock in 1952Q3, so without the + # QC no completion supports it either. A prior no completion supports + # shows the record omits facts, and its named refusal keeps the row + # before the current period's input error (round 23). + row = _row(person, years, month) + _assert_row(row, i.InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY) + assert row.unsupported.detail == ( + "No annual placement supports a listed prior's first insured quarter" + ) @settings(max_examples=24, deadline=None) @@ -373,11 +381,14 @@ def test_plain_date_oracle_applies_two_month_offset_in_both_directions( ending_month, calendar.monthrange(ending_year, ending_month)[1], ) - if mode == "continuity": - end = min( - end, - date.fromordinal(date(1960, fra_month, 1).toordinal() - 1), - ) + fra_end = date.fromordinal(date(1960, fra_month, 1).toordinal() - 1) + if mode == "declared" and end > fra_end: + # A period ends by the month before FRA (404.321(b)), so a later + # declared end has no lawful filling (round 23). + with pytest.raises(i.InvalidFamilyInput, match="statutory FRA end"): + _alternate_case(fra_month=fra_month, end=end) + if mode != "unknown": + end = min(end, fra_end) onset = date(1955, 7, 15) index = end.year * 12 + end.month - 1 - 2 guaranteed = max( diff --git a/tests/test_track_b_insured_status_fix_round_11.py b/tests/test_track_b_insured_status_fix_round_11.py index 1c8bac6d1..8af353d40 100644 --- a/tests/test_track_b_insured_status_fix_round_11.py +++ b/tests/test_track_b_insured_status_fix_round_11.py @@ -145,23 +145,47 @@ def test_review_recent_credit_shortfall_cannot_be_cured_by_deeming( ) -@pytest.mark.parametrize("condition", list(i.CoverageCondition)) -@pytest.mark.parametrize("foreign", [False, True]) -def test_fixed_overlap_precedes_every_flag_and_foreign_route( - condition, foreign -): +def _shared_quarter_person(**kwargs): + """404.321(b)-(c) end a period on a month's last day, so a new period + can begin in the quarter a prior ended (RS00301.140 example 7).""" person = _person( - conditions=(condition,), + onset=date(2022, 2, 15), prior_disability_periods=( - i.DisabilityPeriod(date(2021, 1, 1), date(2022, 1, 14)), + i.DisabilityPeriod(date(2021, 1, 1), date(2022, 1, 31)), ), + **kwargs, ) - person = replace(person, current_disability_period_end=date(2022, 1, 31)) + return replace(person, current_disability_period_end=date(2022, 2, 28)) + + +def test_a_prior_ending_in_the_onset_quarter_leaves_a_valid_start(): + person = _shared_quarter_person() month = date(2023, 1, 1) - _assert_invalid( + result = i.insured_status( + person, history(person, month, _counts(28)), month + ) + assert result.current_disability_period_start == date(2022, 2, 15) + assert result.disability.insured + assert result.disability.qualifying_quarter == date(2022, 1, 1) + + +@pytest.mark.parametrize("condition", list(i.CoverageCondition)) +@pytest.mark.parametrize("foreign", [False, True]) +def test_a_prior_ending_in_the_onset_quarter_keeps_every_route_refusal( + condition, foreign +): + """The shared-quarter record is valid, so each route refuses by name.""" + person = _shared_quarter_person(conditions=(condition,)) + month = date(2023, 1, 1) + _assert_refusal( person, - history(person, month, _counts(20)), + history(person, month, _counts(28)), month, + ( + i.InsuredUnsupportedReason.TOTALIZATION + if foreign + else _reason(condition) + ), totalization_credits=("canada",) if foreign else (), ) diff --git a/tests/test_track_b_insured_status_fix_round_12.py b/tests/test_track_b_insured_status_fix_round_12.py index ffab69762..6add3e9f4 100644 --- a/tests/test_track_b_insured_status_fix_round_12.py +++ b/tests/test_track_b_insured_status_fix_round_12.py @@ -113,15 +113,17 @@ def _fixed_history(person, month, quarters, *, end=None): return years -def _recent_oracle( - person, years, horizon, *, exit_month=None, prior_treatment=None -): +def _recent_oracle(person, years, horizon, *, prior_treatment=None): """Existence under 404.130(b)-(d), without implementation helpers. - Annual counts are assigned to every possible eligible set. Each prior - period is considered together with all the others, or all are ignored. - Credited endpoints remain in the clock; uncredited period quarters do - not. Candidate quarters inside any represented prior period are barred. + Annual counts are assigned to every possible eligible set: any begun + quarter of the year through death, outside a considered prior's + interior (RS00301.230 B, .240). Each prior period is considered + together with all the others, or all are ignored. Credited endpoints + remain in the clock; uncredited period quarters do not. A period ends + on a month's last day (404.321(b)-(c)), so a new one can begin in the + quarter a prior ended (RS00301.140 example 7); a prior that reaches + the onset day bars every candidate it covers. """ first_candidate = _q(person.disability_onset) last_candidate = _q(horizon) @@ -132,6 +134,7 @@ def _recent_oracle( for candidate in range(first_candidate, last_candidate + 1): if any( _q(period.start) <= candidate <= _q(period.end) + and period.end >= person.disability_onset for period in person.prior_disability_periods ): continue @@ -147,12 +150,11 @@ def _recent_oracle( last = min( candidate, _q(person.death_date) if person.death_date else candidate, - _q(exit_month) if exit_month else candidate, ) eligible = tuple( quarter for quarter in range(year * 4, year * 4 + 4) - if _q(person.birth_date) <= quarter <= last + if quarter <= last and not any( _q(period.start) < quarter < _q(period.end) for period in periods @@ -332,6 +334,11 @@ def test_special_recent_requirement_and_one_short(special, short): counts = {} for year in range(2021, 2005, -1): counts[year], total = min(total, 4), max(0, total - 4) + if prior: + # Eighteen QCs in the 36 quarters after age 21 begin the flagged + # prior on 404.130(c), short of 20 of 40 (404.130(d)(1)); a prior + # no completion supports would refuse by name first (round 23). + counts.update({2005: 4, 2006: 4, 2007: 4, 2008: 4, 2009: 2}) years = history(person, month, counts) assert _recent_oracle( person, years, person.current_disability_period_end @@ -356,7 +363,10 @@ def test_subsequent_special_recent_rule_can_pass_below_twenty_qcs(short): ), ) month = date(2023, 1, 1) - counts = {year: 4 for year in range(2018, 2022)} + # Eight QCs in the 16 quarters after age 21 begin the flagged prior on + # 404.130(c), short of 20 of 40; a prior no completion supports would + # refuse by name first (round 23). + counts = {2013: 4, 2014: 4, 2020: 4, 2021: 4} counts[2021] -= short years = history(person, month, counts) # After the age-21 quarter, 44 elapsed quarters minus the 12-quarter @@ -400,7 +410,7 @@ def test_recent_window_uses_all_prior_periods_or_disregards_all(disregard): _refusal(person, years, _reason(FULLY_ROUTES[0]), month) -def test_candidate_inside_prior_period_does_not_supply_recent_witness(): +def test_an_onset_in_a_prior_end_quarter_can_supply_the_recent_witness(): person = _person( birth=date(1910, 2, 2), onset=date(1970, 2, 15), @@ -411,12 +421,19 @@ def test_candidate_inside_prior_period_does_not_supply_recent_witness(): ), ) month = date(1973, 1, 1) - # Disregard yields twenty at the overlapped onset quarter only. The - # first of those QCs ages out before the first usable candidate. + # Disregard yields twenty at the onset quarter only, where the prior + # ended a month before the onset; its first QC ages out a quarter + # later. 404.321 lets the period begin in that shared quarter. credited = {1960 * 4 + 1, *range(1965 * 4, 1969 * 4 + 3)} years = _fixed_history(person, month, credited) - assert not _recent_oracle(person, years, date(1970, 10, 1)) - _invalid(person, years, month) + assert _recent_oracle(person, years, person.disability_onset) + assert _recent_oracle( + person, years, person.disability_onset, prior_treatment=False + ) + assert not _recent_oracle( + person, years, person.disability_onset, prior_treatment=True + ) + _refusal(person, years, _reason(FULLY_ROUTES[0]), month) @pytest.mark.parametrize("condition", FULLY_ROUTES) diff --git a/tests/test_track_b_insured_status_fix_round_13.py b/tests/test_track_b_insured_status_fix_round_13.py index a940be088..cc7a9ea1c 100644 --- a/tests/test_track_b_insured_status_fix_round_13.py +++ b/tests/test_track_b_insured_status_fix_round_13.py @@ -4,6 +4,9 @@ The zero-credit blind and credit-adding cases, six-credit boundary, clear alternate candidate, credited endpoint, and undeclared-period cases pin unchanged behavior. The other cases expose the round-thirteen defects. +Round 23: 404.321(b)-(c) end a period on a month's last day, so a new +period can begin in the quarter a prior ended (RS00301.140 example 7); the +shared-quarter cases now refuse by the route's name or compute. """ from dataclasses import replace @@ -131,10 +134,15 @@ def test_review_unknown_prior_cannot_remove_six_qc_floor(coverage_end): @pytest.mark.parametrize( "end", [date(1956, 3, 31), date(1956, 12, 31), date(1959, 12, 31)] ) -def test_review_alternate_start_must_clear_same_prior_overlap( +def test_an_alternate_start_can_share_the_quarter_a_prior_ended( coverage_end, end ): - """Sol's second case and its two longer-period controls.""" + """Sol's second case and its two longer-period controls. + + The prior ends 1955-11-30, a month before the onset, so the period can + begin in 1955Q4, where RS00301.480 may begin it; the rule refuses by + that route's name. + """ person, years, month = _alternate( onset=date(1955, 12, 15), prior_end=date(1955, 11, 30), end=end ) @@ -144,7 +152,13 @@ def test_review_alternate_start_must_clear_same_prior_overlap( for year, row in years.items() if year <= coverage_end.year } - _invalid(person, years, month, coverage_end_month=coverage_end) + _refusal( + person, + years, + month, + i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956, + coverage_end_month=coverage_end, + ) @pytest.mark.parametrize("condition", FULLY_ROUTES) @@ -230,7 +244,8 @@ def test_foreign_and_credit_adding_routes_precede_floor(condition): def test_alternate_uses_one_clear_candidate_after_prior_ending_quarter( endpoint, ): - """Unchanged: onset Q3 overlaps, but the sole clear Q4 may start.""" + """A prior ending 1955-08-31 shares 1955Q3 with the onset, so 1955Q3 + and 1955Q4 may each start the period on the alternate.""" person, years, month = _alternate( onset=date(1955, 9, 15), prior_end=date(1955, 8, 31), @@ -244,19 +259,33 @@ def test_alternate_uses_one_clear_candidate_after_prior_ending_quarter( ) +@pytest.mark.parametrize( + "test", + [i.InsuredTest.ALL, i.InsuredTest.CURRENTLY, i.InsuredTest.DISABILITY], +) @pytest.mark.parametrize("end", [date(1956, 3, 31), date(1959, 12, 31)]) -def test_post1955_clear_start_cannot_replace_overlapped_alternate(end): +def test_every_test_refuses_a_shared_quarter_alternate_by_name(end, test): + """No post-1955 start replaces the 1955Q4 alternate for any test.""" person, years, month = _alternate( onset=date(1955, 12, 15), prior_end=date(1955, 11, 30), end=end ) - _invalid(person, years, month) + row = i.evaluate_insured_status( + "round-thirteen-shared-alternate", + WEIGHT, + lambda: i.insured_status(person, years, month, test=test), + ) + assert row.result is None + assert ( + row.unsupported.reason + is i.InsuredUnsupportedReason.DISABILITY_BEFORE_1956 + ) @pytest.mark.parametrize( "established", [False, None], ids=["false", "unknown"] ) def test_unestablished_alternate_keeps_prior_treatment(established): - """Unchanged: candidate nonoverlap belongs to established periods.""" + """Unestablished or UNKNOWN establishment keeps the named refusal.""" person, years, month = _alternate( onset=date(1955, 12, 15), prior_end=date(1955, 11, 30) ) @@ -286,8 +315,12 @@ def test_unestablished_alternate_keeps_prior_treatment(established): assert counts.weight == counts.unsupported_weight == WEIGHT -def test_disability_witness_uses_the_legal_annual_start_filling(): - """An unresolved annual start retains its row through a named refusal.""" +def test_disability_witness_counts_the_quarter_a_prior_ended(): + """The prior ends a month before the onset, so 2000Q1 can begin the + period (404.321(b)-(c)). Disregarding the prior (404.130(f)) leaves + 1999's three QCs and 2000's one in the window: 20 of 40 at 2000Q1. Past + blindness can begin the prior with a 1999Q1 QC on that same filling. + """ person = _person( disability_onset=date(2000, 2, 15), conditions=(), @@ -302,18 +335,16 @@ def test_disability_witness_uses_the_legal_annual_start_filling(): month, {1995: 4, 1996: 4, 1997: 4, 1998: 4, 1999: 3, 2000: 1}, ) - row = i.evaluate_insured_status( - "round-thirteen-disability-start-filling", - WEIGHT, - lambda: i.insured_status( - person, years, month, test=i.InsuredTest.DISABILITY - ), + result = i.insured_status( + person, years, month, test=i.InsuredTest.DISABILITY ) - assert row.result is None + assert result.current_disability_period_start == date(2000, 2, 15) + decision = result.disability + assert decision.insured + assert decision.rule == "disability_20_of_40" assert ( - row.unsupported.reason - is i.InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY - ) - counts = count_family_outcomes((row,)) - assert counts.rows == counts.unsupported_rows == 1 - assert counts.weight == counts.unsupported_weight == WEIGHT + decision.qc_count_lower, + decision.qc_count_upper, + decision.required, + ) == (20, 20, 20) + assert decision.qualifying_quarter == date(2000, 1, 1) diff --git a/tests/test_track_b_insured_status_fix_round_14.py b/tests/test_track_b_insured_status_fix_round_14.py index 91b8bcae2..422a3937a 100644 --- a/tests/test_track_b_insured_status_fix_round_14.py +++ b/tests/test_track_b_insured_status_fix_round_14.py @@ -3,6 +3,10 @@ Invented declarations only; no population, behavioral, or forecast claim. Rows and exact weight survive every named refusal. Tests named ``unchanged`` pin existing rejection or refusal behavior rather than a new defect. +Round 23: 404.321(b)-(c) end a period on a month's last day, so a new period +can begin in the quarter a prior ended (RS00301.140 example 7). The records +whose onset shares 2000Q1 (or 1962Q1, 1985Q1) with a prior's last quarter +now compute from the onset day or refuse by a declared route's name. """ from dataclasses import replace @@ -252,6 +256,45 @@ def test_unchanged_unflagged_disregard_control_is_fully_insured(): assert row.result.fully.insured +def _decision(decision): + if decision is None: + return None + return ( + decision.insured, + decision.qc_count_lower, + decision.qc_count_upper, + decision.required, + decision.qualifying_quarter, + ) + + +def _dli(result): + return result.dli.lower, result.dli.upper, result.dli.right_censored + + +# Considering the prior (404.130(f)), 2000Q1's QC and 1999Q1's join 1990's +# and 1995-1998's: 19 of 40 at 2000Q1. Disregarding it counts both 1999 +# QCs: 20 of 40. Placement can begin the period in 2000Q1, Q2 or Q3, each +# with the same statuses and a last insured quarter of 2003Q4, and a 2002 +# start loses FULLY (the status oracle's per-start search), so the earliest +# start, the onset day, stands (us:oasdi-insured-one-filling-first-start). +PLACEMENT = { + "ordinary-query": ( + (True, 20, 20, 20, date(2006, 1, 1)), + (False, 0, 0, 6, None), + (True, 20, 20, 20, date(2000, 1, 1)), + date(2003, 12, 31), + ), + "claiming-age": ( + (True, 36, 36, 36, date(2022, 1, 1)), + (False, 0, 0, 6, None), + (True, 20, 20, 20, date(2000, 1, 1)), + date(2011, 12, 31), + ), +} +PLACEMENT["coverage-end"] = PLACEMENT["ordinary-query"] + + @pytest.mark.parametrize("test", tuple(i.InsuredTest)) @pytest.mark.parametrize( "month,coverage_end,claiming", @@ -262,7 +305,7 @@ def test_unchanged_unflagged_disregard_control_is_fully_insured(): ), ids=("ordinary-query", "coverage-end", "claiming-age"), ) -def test_first_successful_placement_cannot_settle_status( +def test_one_onset_year_qc_starts_the_period_on_the_onset_day( test, month, coverage_end, claiming ): person, years, month = _placement_history( @@ -270,28 +313,64 @@ def test_first_successful_placement_cannot_settle_status( coverage_end=coverage_end, claiming=claiming, ) - _refusal( - person, - years, - month, - i.InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, - test=test, - coverage_end=coverage_end, - ) + row = _row(person, years, month, test=test, coverage_end=coverage_end) + result = row.result + assert result.current_disability_period_start == date(2000, 2, 15) + variant = "claiming-age" if claiming else "ordinary-query" + fully, currently, disability, dli = PLACEMENT[variant] + every = test is i.InsuredTest.ALL + assert _decision(result.fully) == ( + fully if every or test is i.InsuredTest.FULLY else None + ) + assert _decision(result.currently) == ( + currently if every or test is i.InsuredTest.CURRENTLY else None + ) + if every or test is i.InsuredTest.DISABILITY: + assert _decision(result.disability) == disability + assert _dli(result) == (dli, dli, False) + else: + assert result.disability is None -def test_round_thirteen_annual_start_needs_named_refusal(): +@pytest.mark.parametrize("test", tuple(i.InsuredTest)) +def test_two_onset_year_qcs_leave_the_start_to_placement(test): + """Two 2000 QCs can begin the period in 2000Q1 or later. A 2000Q1 start + keeps disability insured status through 2004Q4, and a 2000Q2 start keeps + it through the 2006Q1 query (``favorable_statuses`` in the status + oracle), so DISABILITY refuses by name while FULLY and CURRENTLY stand + on either start.""" + person, years, month = _placement_history() + years[2000] = replace(years[2000], qc_count=2) + row = _row(person, years, month, test=test) + if test in (i.InsuredTest.ALL, i.InsuredTest.DISABILITY): + assert row.result is None + assert ( + row.unsupported.reason + is i.InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY + ) + return + assert row.result.current_disability_period_start == date(2000, 2, 15) + if test is i.InsuredTest.FULLY: + assert _decision(row.result.fully) == PLACEMENT["ordinary-query"][0] + else: + assert _decision(row.result.currently) == (False, 0, 0, 6, None) + + +def test_round_thirteen_annual_start_computes_in_the_shared_quarter(): person, years, month = _placement_history( month=date(2001, 1, 1), round_thirteen=True, ) - _refusal( - person, - years, - month, - i.InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, - test=i.InsuredTest.DISABILITY, + row = _row(person, years, month, test=i.InsuredTest.DISABILITY) + assert row.result.current_disability_period_start == date(2000, 2, 15) + assert _decision(row.result.disability) == ( + True, + 20, + 20, + 20, + date(2000, 1, 1), ) + assert _dli(row.result) == (date(2001, 3, 31), date(2001, 3, 31), True) def _invalid(person, years, month, *, match="no possible insured", **kwargs): @@ -304,16 +383,18 @@ def _invalid(person, years, month, *, match="no possible insured", **kwargs): @pytest.mark.parametrize("flag", FULLY_FLAGS) -def test_unchanged_ordinary_overlap_cannot_be_delayed_by_a_flag(flag): - """Ordinary insurance at onset in every placement fixes the start.""" +def test_ordinary_insurance_in_a_shared_onset_quarter_keeps_flag_refusal( + flag, +): + """Ordinary insurance at the onset, in a quarter a prior ended, begins + the period there, and the flag refuses by its name.""" person = _person(conditions=(flag,)) month = date(2006, 1, 1) years = history(person, month, {year: 4 for year in range(1985, 2001)}) - _invalid(person, years, month) + _refusal(person, years, month, i.InsuredUnsupportedReason[flag.name]) -@pytest.mark.parametrize("flag", FULLY_FLAGS) -def test_unchanged_1962_ordinary_overlap_fixes_start(flag): +def _shared_1962(flag): person = _person( birth=date(1910, 2, 2), disability_onset=date(1962, 2, 15), @@ -321,30 +402,44 @@ def test_unchanged_1962_ordinary_overlap_fixes_start(flag): prior_disability_periods=( i.DisabilityPeriod(date(1960, 1, 1), date(1962, 1, 31)), ), - conditions=(flag,), + conditions=(() if flag is None else (flag,)), ) month = date(1968, 1, 1) years = history(person, month) - credited = {*range(1957 * 4, 1961 * 4 + 3), 1962 * 4} + # 1955-1956 give the prior 21 of 40 at its 1960Q1 start (404.130(b)). + credited = {*range(1955 * 4, 1961 * 4 + 3), 1962 * 4} for year in years: years[year] = i.CoverageYear( OBSERVED, qc_quarters=tuple(year * 4 + q in credited for q in range(4)), ) - _invalid(person, years, month) + return person, years, month + + +@pytest.mark.parametrize("flag", (None, *FULLY_FLAGS)) +def test_1962_ordinary_insurance_in_a_shared_quarter_fixes_start(flag): + person, years, month = _shared_1962(flag) + if flag is not None: + _refusal(person, years, month, i.InsuredUnsupportedReason[flag.name]) + return + row = _row(person, years, month, test=i.InsuredTest.DISABILITY) + assert row.result.current_disability_period_start == date(1962, 2, 15) + assert row.result.disability.insured + assert row.result.disability.qualifying_quarter == date(1962, 1, 1) @pytest.mark.parametrize("flag", FULLY_FLAGS) -@pytest.mark.parametrize("overlap", (False, True)) -def test_blind_flagged_zero_qcs_keep_named_refusal(flag, overlap): - """The clear-onset case is unchanged; an overlap admits a free flag start.""" +@pytest.mark.parametrize("shared", (False, True)) +def test_blind_flagged_zero_qcs_keep_named_refusal(flag, shared): + """A prior ending before the onset quarter or inside it keeps the flag's + named refusal.""" person = _person( statutory_blindness=True, conditions=(flag,), prior_disability_periods=( i.DisabilityPeriod( date(1999, 1, 1), - date(2000, 1, 31) if overlap else date(1999, 12, 31), + date(2000, 1, 31) if shared else date(1999, 12, 31), ), ), ) @@ -357,12 +452,20 @@ def test_blind_flagged_zero_qcs_keep_named_refusal(flag, overlap): ) -@pytest.mark.parametrize("flag", FULLY_FLAGS) -def test_unchanged_blind_ordinary_fully_insured_overlap_is_invalid(flag): - person = _person(statutory_blindness=True, conditions=(flag,)) +@pytest.mark.parametrize("flag", (None, *FULLY_FLAGS)) +def test_blind_fully_insured_onset_in_a_shared_quarter_starts_there(flag): + person = _person( + statutory_blindness=True, + conditions=(() if flag is None else (flag,)), + ) month = date(2006, 1, 1) years = history(person, month, {year: 4 for year in range(1985, 2001)}) - _invalid(person, years, month) + if flag is not None: + _refusal(person, years, month, i.InsuredUnsupportedReason[flag.name]) + return + row = _row(person, years, month, test=i.InsuredTest.DISABILITY) + assert row.result.current_disability_period_start == date(2000, 2, 15) + assert row.result.disability.insured @pytest.mark.parametrize("total", (5, 6)) @@ -378,19 +481,31 @@ def test_unchanged_unknown_prior_needs_a_possible_fully_insured_start(total): _invalid(person, history(person, month, {1998: 4, 1999: total - 4}), month) -def test_unchanged_no_placement_can_clear_the_prior_overlap(): +def test_a_shared_onset_quarter_is_a_valid_start(): + """Every placement insures 2000Q1, which the prior ended in a month + before the onset, so the period begins on the onset day.""" person = _person() month = date(2006, 1, 1) years = history(person, month, {year: 4 for year in range(1985, 2001)}) - _invalid(person, years, month) + row = _row(person, years, month, test=i.InsuredTest.ALL) + assert row.result.current_disability_period_start == date(2000, 2, 15) + assert _decision(row.result.disability) == ( + True, + 40, + 40, + 20, + date(2000, 1, 1), + ) + assert row.result.fully.insured @pytest.mark.parametrize("flag", (None, *FULLY_FLAGS)) -def test_one_treatment_overlaps_and_the_other_leaves_a_clear_start(flag): +def test_the_treatment_that_insures_the_shared_quarter_fixes_the_start(flag): # Move four old QCs into the used-prior recent window, keeping the - # lifetime count unchanged. Use now insures the overlapping Q1: - # 20 recent and 29/27 fully. Disregard still has only 33/34 fully - # in Q1, first becoming insured in the clear Q2 with 34/34. + # lifetime count unchanged. Use now insures the shared Q1: 20 recent + # and 29/27 fully. Disregard still has only 33/34 fully in Q1, first + # becoming insured in Q2 with 34/34. The prior ended a month before + # the onset, so Q1 begins the period on the onset day. person, years, month = _flag_history(flag) years[1951] = i.CoverageYear( OBSERVED, qc_quarters=(False, False, False, False) @@ -401,16 +516,25 @@ def test_one_treatment_overlaps_and_the_other_leaves_a_clear_start(flag): years[1975] = i.CoverageYear( OBSERVED, qc_quarters=(True, True, True, True) ) - _refusal( - person, - years, - month, - ( - i.InsuredUnsupportedReason[flag.name] - if flag - else i.InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY - ), - weight=FLAG_WEIGHT, + if flag: + _refusal( + person, + years, + month, + i.InsuredUnsupportedReason[flag.name], + weight=FLAG_WEIGHT, + ) + return + row = _row( + person, years, month, test=i.InsuredTest.ALL, weight=FLAG_WEIGHT + ) + assert row.result.current_disability_period_start == date(1985, 2, 15) + assert _decision(row.result.disability) == ( + True, + 20, + 20, + 20, + date(1985, 1, 1), ) @@ -482,21 +606,21 @@ def test_fully_route_flag_only_relaxes_deterministic_lattice(): @PROPERTY -@example(old=2, onset=1, blind=False, overlap=True, historical=True) -@example(old=2, onset=1, blind=False, overlap=True, historical=False) +@example(old=2, onset=1, blind=False, shared=True, historical=True) +@example(old=2, onset=1, blind=False, shared=True, historical=False) @given( old=st.integers(0, 4), onset=st.integers(0, 4), blind=st.booleans(), - overlap=st.booleans(), + shared=st.booleans(), historical=st.booleans(), ) def test_fully_route_flag_only_relaxes_generated_declarations( - old, onset, blind, overlap, historical + old, onset, blind, shared, historical ): if historical: person, years, month = _flag_history( - None, month=date(1986, 1, 1) if overlap else date(1985, 12, 1) + None, month=date(1986, 1, 1) if shared else date(1985, 12, 1) ) _assert_flags_only_relax(person, years, month) return @@ -505,7 +629,7 @@ def test_fully_route_flag_only_relaxes_generated_declarations( prior_disability_periods=( i.DisabilityPeriod( date(1999, 1, 1), - date(2000, 1, 31) if overlap else date(1999, 12, 31), + date(2000, 1, 31) if shared else date(1999, 12, 31), ), ), ) diff --git a/tests/test_track_b_insured_status_fix_round_17.py b/tests/test_track_b_insured_status_fix_round_17.py index 0c8ab5b59..e49dfaa9c 100644 --- a/tests/test_track_b_insured_status_fix_round_17.py +++ b/tests/test_track_b_insured_status_fix_round_17.py @@ -6,8 +6,9 @@ Act 223(c)(1)(B)(iii) and 216(i)(3)(B)(iii) count "the quarters beginning after such individual attained age 21", with no cap. 404.130(d)(2) adds "up to a maximum of 20 QCs out of 40 calendar quarters". Past 40 counted quarters the -Act takes half the whole period and the regulation takes 20 of the last 40, and -the rule refuses by name wherever they differ (source conflict +Act takes half the whole period and the regulation, read with the 40 counted +quarters ending with the tested one, takes 20 of those, and the rule refuses by +name wherever they differ (source conflict us:oasdi-insured-subsequent-special-long-period). Each period ending's favorable date last insured can rest on a placement that @@ -286,7 +287,8 @@ def test_a_later_date_last_insured_can_turn_on_a_reading(): def test_twenty_qcs_short_of_half_the_period_compute(): # The 20th QC arrives in 1994, when half the 53 counted quarters is 26, and # the last 40 hold 10. Only a parse that drops "out of 40 calendar - # quarters" insures this record, and the rule takes no such parse. The 14 + # quarters" insures this record, and the rule takes no such parse; the + # register lists it for Max (round 23). The 14 # QCs through 1985 last meet half in 1988Q4, where 29 quarters reduce to 28. counts = {1981: 3, 1982: 3, 1984: 4, 1985: 4, 1993: 4, 1994: 2} result = _result( diff --git a/tests/test_track_b_insured_status_fix_round_22.py b/tests/test_track_b_insured_status_fix_round_22.py index 1ff5ae27b..ab3b017e7 100644 --- a/tests/test_track_b_insured_status_fix_round_22.py +++ b/tests/test_track_b_insured_status_fix_round_22.py @@ -194,6 +194,9 @@ def test_an_unknown_year_refuses(): def test_a_current_period_after_that_prior_refuses(): + # Disregarding the prior (404.130(f)), every placement insures the 2004Q1 + # onset, so the prior's basis is what placement decides, and the detail + # names it (round 23). refused = _refusal( _young( disability_onset=date(2004, 1, 1), @@ -205,7 +208,7 @@ def test_a_current_period_after_that_prior_refuses(): MONTH, ) assert refused.reason is ASSIGNMENT - assert refused.detail.startswith("First insured start depends") + assert refused.detail == LISTED_PRIOR def test_a_flagged_prior_there_computes(): diff --git a/tests/test_track_b_insured_status_fix_round_23.py b/tests/test_track_b_insured_status_fix_round_23.py new file mode 100644 index 000000000..fc6655175 --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_23.py @@ -0,0 +1,1299 @@ +"""Round 23: a period keeps the basis it began on; an exit bars later years. + +Verification class: statutory conformance on invented declarations; no +population, behavioral or forecast claim. + +A current period that began before age 31 on 404.130(c) alone, where +404.130(b) fails at its first quarter, is one "for which you were only +insured under paragraph (c)" (404.130(d)(1)). Once it ends, the rule counts it +as a flagged prior, so 404.130(d) reaches the quarters after it at 31 or +later; where annual placement or an UNKNOWN year decides that basis and the +two bases give different dates, the date refuses by name. A period begins on +its onset day or on the first day of a later insured quarter (404.321(a)), +so it can share the quarter a prior ended in, as RS 00301.140 example 7 +shows. A coverage exit or a birth bars no quarter of its own year: an annual +QC takes any begun quarter through death (404.146). + +Where a listed prior binds, DISABILITY's qualifying quarters span every basis +the record leaves open, and under UNKNOWN priors they reach the onset quarter. +The rule ends a living man's elapsed years at his retirement age once he +reaches 62 (404.110(b)(2)(iii)-(iv)). A flagged prior needs one placement +where 404.130(c) holds and 404.130(b) fails. A listed prior that no +completion supports refuses by name before any input error or UNKNOWN-earnings +refusal the record would raise. Past blindness can begin a listed prior only +from January 1973 (RS 00301.150 A). +""" + +import re +from datetime import date, timedelta +from fractions import Fraction +from pathlib import Path + +import pytest +from hypothesis import given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as i +from populace_dynamics.track_b.gross_benefits import count_family_outcomes +from tests.test_track_b_insured_status import history +from tests.test_track_b_insured_status_fix_round_4_routes import ( + _pre1956_case, +) +from tests.test_track_b_insured_status_sources import source_text + +OBSERVED = i.EarningsProvenance.OBSERVED +UNKNOWN = i.EarningsProvenance.UNKNOWN +FEMALE = i.Sex.FEMALE +MALE = i.Sex.MALE +ALL = i.InsuredTest.ALL +FULLY = i.InsuredTest.FULLY +CURRENTLY = i.InsuredTest.CURRENTLY +DISABILITY = i.InsuredTest.DISABILITY +Reason = i.InsuredUnsupportedReason +WEIGHT = Fraction(5, 2) +PROPERTY = settings(max_examples=25, deadline=None) +UNSUPPORTED_PRIOR = ( + "No annual placement supports a listed prior's first insured quarter" +) +LISTED_PRIOR = ( + "Annual placement decides a listed prior's first insured quarter" +) + + +def _person(birth, *priors, onset=None, established=False, **changes): + values = dict( + sex=FEMALE, + prior_disability_periods=priors, + prior_disability_periods_provenance=OBSERVED, + sspa211_applies=False, + sspa211_provenance=OBSERVED, + ) + if onset is not None: + values.update( + disability_onset=onset, + current_disability_period_established=established, + current_disability_period_provenance=OBSERVED, + ) + values.update(changes) + return i.Person(birth, **values) + + +def _ended(birth, onset, end, *priors, **changes): + return _person( + birth, + *priors, + onset=onset, + established=True, + current_disability_period_end=end, + current_disability_period_end_provenance=OBSERVED, + **changes, + ) + + +def _row(person, years, month, **options): + return i.evaluate_insured_status( + "round-23", + WEIGHT, + lambda: i.insured_status(person, years, month, **options), + ) + + +def _computed(person, years, month, **options): + row = _row(person, years, month, **options) + assert row.unsupported is None, row.unsupported + return row.result + + +def _refused(reason, person, years, month, **options): + row = _row(person, years, month, **options) + assert row.result is None, row.result + assert row.unsupported.reason is reason, row.unsupported + counts = count_family_outcomes((row,)) + assert (counts.rows, counts.weight) == (1, WEIGHT) + assert (counts.unsupported_rows, counts.unsupported_weight) == (1, WEIGHT) + return row.unsupported.detail + + +def _dli(result): + return result.dli.lower, result.dli.upper, result.dli.right_censored + + +def _month_end(year, month): + return date(year + month // 12, month % 12 + 1, 1) - timedelta(days=1) + + +# A current period begun on 404.130(c) alone. + +M1_BIRTH = date(1980, 2, 2) +M1_ONSET = date(2003, 1, 15) +M1_END = date(2004, 12, 31) +M1_MONTH = date(2013, 1, 1) +M1_ANNUAL = {2001: 2, 2002: 4, 2009: 4, 2010: 4, 2011: 4, 2012: 1} + + +def _m1_years(annual=M1_ANNUAL, month=M1_MONTH, **options): + return history(_person(M1_BIRTH), month, annual, **options) + + +def test_a_period_begun_on_paragraph_c_alone_opens_paragraph_d_after_it(): + # Plain arithmetic: she attains 21 in 2001Q1. At 2003Q1 the 12 quarters + # from 2000Q2 hold the six QCs of 2001 and 2002, so 404.130(c) holds, and + # 404.130(b) finds six of 40: the period began on 404.130(c) alone. At + # 2012Q4, past the 2011Q1 quarter she attains 31, 404.130(d) counts the + # 47 quarters from 2001Q2 less the period's eight, an odd 39 it reduces to + # 38, and the 19 QCs meet half. At 2013Q1 its cap asks 20 of 40. + person = _ended(M1_BIRTH, M1_ONSET, M1_END) + result = _computed(person, _m1_years(), M1_MONTH) + assert result.current_disability_period_start == M1_ONSET + assert result.disability.insured + assert result.disability.rule == "under31_special" + assert _dli(result) == (date(2012, 12, 31), date(2012, 12, 31), False) + + +def test_the_flag_reaches_a_frozen_exit_and_a_later_record(): + # The frozen exit keeps the same QCs, so the same 2012Q4 holds. + person = _ended(M1_BIRTH, M1_ONSET, M1_END) + exit_month = date(2012, 12, 1) + years = _m1_years(end=exit_month) + result = _computed( + person, years, date(2027, 1, 1), coverage_end_month=exit_month + ) + assert _dli(result) == (date(2012, 12, 31), date(2012, 12, 31), False) + # A second record: eight QCs in 2003 and 2004 begin a 2005 period on + # 404.130(c), and 404.130(d) holds through the 2016Q1 query quarter. + person = _ended(date(1980, 2, 15), date(2005, 6, 1), date(2013, 12, 31)) + month = date(2016, 1, 1) + years = history(person, month, {2003: 4, 2004: 4, 2014: 4, 2015: 4}) + result = _computed(person, years, month) + assert result.disability.rule == "under31_special" + assert _dli(result) == (date(2016, 3, 31), date(2016, 3, 31), True) + + +def test_an_unknown_end_spans_the_flagged_period_lengths(): + # Ending 2003-06-30, the period leaves 404.130(c) 13 counted quarters at + # 2004Q4, reduced to 12, and the six QCs meet half; 2005Q1 asks seven. + # Ending in 2005 or later, 404.130(d) holds through the query quarter. + person = _person( + M1_BIRTH, + onset=M1_ONSET, + established=True, + current_disability_period_continues_through=date(2003, 6, 30), + current_disability_period_continues_through_provenance=OBSERVED, + ) + result = _computed(person, _m1_years(), M1_MONTH) + assert _dli(result) == (date(2004, 12, 31), date(2013, 3, 31), True) + + +def test_one_more_qc_can_bring_the_dli_earlier_intended(): + # Intended violation of QC monotonicity, under the law: with 19 QCs + # before the onset, 404.130(b) fails at 2003Q1, the period rests on + # 404.130(c) alone, and 404.130(d) holds through 2012Q4. A second 1997 + # QC makes 20 of 40 at 2003Q1, so 404.130(b) began the period and + # 404.130(d) never applies; 20 of 40 then last holds at 2012Q3. + person = _ended(M1_BIRTH, M1_ONSET, M1_END) + dlis = [] + for qcs_1997 in (1, 2): + annual = {**M1_ANNUAL, 1997: qcs_1997, 1998: 4, 1999: 4, 2000: 4} + dlis.append(_dli(_computed(person, _m1_years(annual), M1_MONTH))) + assert dlis == [ + (date(2012, 12, 31), date(2012, 12, 31), False), + (date(2012, 9, 30), date(2012, 9, 30), False), + ] + + +BASIS_DECIDED = ( + "Annual placement or an unknown year decides whether the current period " + "rested on 404.130(c) alone" +) + + +def test_a_placement_or_year_that_decides_the_basis_refuses(): + # Differential: 404.130(b) at 2003Q1 counts 1993Q2 to 2003Q1, so 19 QCs + # there leave the period on 404.130(c) alone and 20 begin it on + # 404.130(b); 1993 enters no later count. One 1993 QC therefore gives the + # 19-QC date in 1993Q1 and the 20-QC date in 1993Q2 to Q4, so its + # placement decides the date, as an UNKNOWN 1997 does. FULLY reports no + # date, and computes. + person = _ended(M1_BIRTH, M1_ONSET, M1_END) + base = {**M1_ANNUAL, 1997: 1, 1998: 4, 1999: 4, 2000: 4} + late, early = date(2012, 12, 31), date(2012, 9, 30) + for qcs_1997, dli in ((0, late), (1, late), (2, early), (4, early)): + years = _m1_years({**base, 1997: qcs_1997}) + assert _dli(_computed(person, years, M1_MONTH)) == (dli, dli, False) + placed = _m1_years({**base, 1993: 1}) + unknown = _m1_years(base) + unknown[1997] = i.CoverageYear(UNKNOWN) + for years, reason in ( + (placed, Reason.ASSIGNMENT_COMPLEXITY), + (unknown, Reason.UNKNOWN_EARNINGS), + ): + for test in (DISABILITY, ALL): + detail = _refused(reason, person, years, M1_MONTH, test=test) + assert detail == BASIS_DECIDED + _computed(person, years, M1_MONTH, test=FULLY) + + +M1_ENDS = tuple( + _month_end(year, month) + for year in range(2003, 2013) + for month in (3, 6, 9, 12) + if (year, month) >= (2003, 6) +) + + +@PROPERTY +@given( + qcs_1997=st.integers(0, 4), + qcs_2001=st.integers(1, 4), + qcs_2002=st.integers(2, 4), + qcs_2012=st.integers(0, 4), + end=st.sampled_from(M1_ENDS), +) +def test_an_ended_current_period_counts_as_the_prior_it_becomes( + qcs_1997, qcs_2001, qcs_2002, qcs_2012, end +): + # Differential: the 1997 to 2002 QCs all sit in the 40 quarters ending + # 2003Q1, so 404.130(b) holds there on every placement or on none, and + # the period's flag follows. The same period listed as a prior with that + # flag has the same DLI. + annual = { + 1997: qcs_1997, + 1998: 4, + 1999: 4, + 2000: 4, + 2001: qcs_2001, + 2002: qcs_2002, + 2009: 4, + 2010: 4, + 2011: 4, + 2012: qcs_2012, + } + years = _m1_years(annual) + row = _row(_ended(M1_BIRTH, M1_ONSET, end), years, M1_MONTH) + if row.result is None: + return + special = qcs_1997 + 12 + qcs_2001 + qcs_2002 < 20 + listed = _person( + M1_BIRTH, + i.DisabilityPeriod( + row.result.current_disability_period_start, + end, + special_insured=special, + ), + ) + assert _dli(_computed(listed, years, M1_MONTH)) == _dli(row.result) + + +# A period that shares the quarter a prior ended in. + +JANE = i.DisabilityPeriod( + date(1988, 3, 29), date(1990, 10, 31), special_insured=True +) +JANE_ANNUAL = {1986: 3, 1987: 3} +JANE_MONTH = date(1991, 1, 1) + + +def test_rs00301_140_example_7_quotes_the_shared_quarter(): + quote = ( + "Their period of disability ceased 8/90 and terminated the last day " + "of 10/90. They became disabled again 12/3/90." + ) + assert quote in source_text("poms_rs_00301_140") + + +def test_rs00301_140_example_7_begins_on_the_onset_day(): + # Plain arithmetic: the prior's quarters 1988Q1 to 1990Q4 hold no QC, so + # 404.130(c) reaches back to the 12 quarters 1985Q1 to 1987Q4, which hold + # the six QCs. The period begins on the onset day, in the quarter the + # prior ended. + for established in (True, False): + person = _person( + date(1967, 3, 16), + JANE, + onset=date(1990, 12, 3), + established=established, + ) + result = _computed( + person, history(person, JANE_MONTH, JANE_ANNUAL), JANE_MONTH + ) + assert result.disability.insured + assert result.disability.rule == "under31_special" + assert result.disability.qualifying_quarter == date(1990, 10, 1) + assert result.current_disability_period_start == ( + date(1990, 12, 3) if established else None + ) + + +@PROPERTY +@given(onset=st.dates(date(1990, 11, 1), date(1990, 12, 31))) +def test_any_onset_after_the_prior_day_keeps_its_own_start(onset): + person = _person(date(1967, 3, 16), JANE, onset=onset, established=True) + result = _computed( + person, history(person, JANE_MONTH, JANE_ANNUAL), JANE_MONTH + ) + assert result.current_disability_period_start == onset + + +def test_periods_still_may_not_share_a_day(): + person = _person( + date(1967, 3, 16), JANE, onset=date(1990, 10, 31), established=True + ) + years = history(person, JANE_MONTH, JANE_ANNUAL) + with pytest.raises(i.InvalidFamilyInput, match="must precede"): + i.insured_status(person, years, JANE_MONTH) + with pytest.raises(i.InvalidFamilyInput, match="overlap"): + _person( + date(1967, 3, 16), + JANE, + i.DisabilityPeriod(date(1990, 10, 31), date(1990, 12, 31)), + ) + # A second listed period may begin in 1990Q4 the day after. + second = i.DisabilityPeriod( + date(1990, 12, 3), date(1991, 6, 30), special_insured=True + ) + person = _person(date(1967, 3, 16), JANE, second) + month = date(1992, 1, 1) + result = _computed(person, history(person, month, JANE_ANNUAL), month) + assert result.disability.insured + + +# A coverage exit bars only later years. + + +def test_an_exit_year_credits_any_begun_quarter(): + # Plain arithmetic: $6,000 of 2020 wages give four QCs at $1,410 each, + # and every 2020 quarter has begun by 2024, so 2019's two make six. + person = _person(date(2000, 6, 15)) + month = date(2024, 1, 1) + results = [] + for exit_month in (date(2020, 2, 1), date(2020, 12, 1)): + years = history(person, month, {2019: 2}, end=exit_month) + years[2020] = i.CoverageYear(OBSERVED, wages=Fraction(6000)) + results.append( + _computed( + person, + years, + month, + test=FULLY, + coverage_end_month=exit_month, + ) + ) + assert [r.qcs_by_year[2020] for r in results] == [(4, 4), (4, 4)] + assert [ + (r.fully.insured, r.fully.qc_count_lower, r.fully.required) + for r in results + ] == [(True, 6, 6), (True, 6, 6)] + + +def test_forty_qcs_need_no_later_quarter(): + # Act 214(a)(2): 40 QCs make anyone fully insured, and the April 2005 exit + # leaves all four 2005 QCs. + person = _person(date(1955, 6, 15)) + exit_month = date(2005, 4, 1) + month = date(2016, 6, 1) + years = history( + person, month, {y: 4 for y in range(1996, 2006)}, end=exit_month + ) + result = _computed( + person, years, month, test=FULLY, coverage_end_month=exit_month + ) + assert result.fully.insured + assert result.fully.qc_count_lower == 40 + + +def test_an_unknown_exit_year_refuses_whatever_its_exit_month(): + person = _person(date(2000, 2, 2)) + month = date(2027, 1, 1) + for exit_month in (date(2026, 4, 1), date(2026, 12, 1)): + years = history(person, month, {2024: 3}, end=exit_month) + years[2026] = i.CoverageYear(UNKNOWN) + _refused( + Reason.UNKNOWN_EARNINGS, + person, + years, + month, + coverage_end_month=exit_month, + ) + + +def test_an_established_period_keeps_its_row_after_a_february_exit(): + # Plain arithmetic: 2020's four QCs and 2016 to 2019's 16 make 20 of the + # 40 quarters ending 2021Q1, so the period begins on the onset day. Ended + # in April 2021, it leaves 2016 to 2020's 20 QCs in the 40 counted + # quarters through 2026Q2, and 2026Q3 loses 2016Q1. + month = date(2021, 6, 1) + exit_month = date(2020, 2, 1) + annual = {y: 4 for y in (*range(2001, 2011), *range(2016, 2020))} + + def years(person): + out = history(person, month, annual, end=exit_month) + out[2020] = i.CoverageYear(OBSERVED, wages=Fraction(6000)) + return out + + onset = date(2021, 1, 15) + person = _person(date(1970, 6, 15), onset=onset, established=True) + for test in (FULLY, CURRENTLY): + result = _computed( + person, + years(person), + month, + test=test, + coverage_end_month=exit_month, + ) + assert result.current_disability_period_start == onset + for test in (DISABILITY, ALL): + _refused( + Reason.CURRENT_PERIOD_DLI, + person, + years(person), + month, + test=test, + coverage_end_month=exit_month, + ) + person = _ended(date(1970, 6, 15), onset, date(2021, 4, 30)) + result = _computed( + person, years(person), month, coverage_end_month=exit_month + ) + assert result.disability.insured + assert _dli(result) == (date(2026, 6, 30), date(2026, 6, 30), False) + + +@PROPERTY +@given( + qcs_2019=st.integers(0, 4), + qcs_2020=st.integers(0, 4), + exit_month=st.integers(1, 12), +) +def test_the_exit_month_moves_nothing_in_its_year( + qcs_2019, qcs_2020, exit_month +): + # An exit bars later years only, so every exit month of 2020 gives the + # December exit's result. + person = _person(date(2000, 6, 15)) + month = date(2024, 1, 1) + + def result(exit_day): + years = history( + person, month, {2019: qcs_2019, 2020: qcs_2020}, end=exit_day + ) + found = i.insured_status( + person, years, month, coverage_end_month=exit_day + ) + return ( + found.fully, + found.currently, + found.disability, + _dli(found), + dict(found.qcs_by_year), + ) + + assert result(date(2020, exit_month, 1)) == result(date(2020, 12, 1)) + + +def test_a_birth_year_credits_quarters_before_the_birth(): + # 404.143(a) credits $3,120 of 2000 wages as four QCs, and 404.146 bars + # no quarter for a birth. + person = _person(date(2000, 12, 15), death_date=date(2003, 3, 10)) + month = date(2004, 1, 1) + years = history(person, month, {2001: 2}) + years[2000] = i.CoverageYear(OBSERVED, wages=Fraction(3120)) + result = _computed(person, years, month, test=FULLY) + assert result.qcs_by_year[2000] == (4, 4) + assert (result.fully.insured, result.fully.qc_count_lower) == (True, 6) + + +# A listed prior's qualifying quarters on every basis. + +M4_PRIOR = i.DisabilityPeriod(date(1998, 1, 1), date(1999, 12, 31)) +M4_ANNUAL = { + **{y: 4 for y in range(1989, 1993)}, + 1993: 3, + 1998: 1, + **{y: 4 for y in range(1999, 2003)}, + 2003: 2, +} + + +def test_a_binding_prior_keeps_the_earliest_qualifying_quarter(): + # Plain arithmetic: the filling 1990Q3, 1991Q1-Q3, 1992Q2-Q4 and 2000Q1 + # begins the prior on 404.130(b) at 2000Q2, with 20 of 40, and holds 20 + # in the 40 counted quarters ending 2007Q1. + prior = i.DisabilityPeriod(date(2000, 4, 1), date(2005, 3, 31)) + annual = { + 1990: 1, + 1991: 3, + 1992: 3, + 1994: 4, + 1997: 4, + 1998: 4, + 2000: 1, + 2006: 4, + 2009: 4, + 2010: 4, + } + month = date(2011, 9, 1) + for established in (False, True): + person = _person( + date(1959, 2, 28), + prior, + onset=date(2007, 1, 1), + established=established, + ) + result = _computed(person, history(person, month, annual), month) + assert result.disability.qualifying_quarter == date(2007, 1, 1) + assert result.disability.upper_qualifying_quarter == date(2007, 1, 1) + assert result.current_disability_period_start == ( + date(2007, 1, 1) if established else None + ) + assert "prior_disability_period_basis" not in result.unknown_facts + + +def test_a_prior_basis_split_widens_the_qualifying_quarters(): + # On 404.130(b) the 1998 QC sits in 1998Q1, and 2008Q2 first holds 20 of + # 40. On past blindness it may sit later, and 2008Q1 holds 20. + person = _person(date(1968, 2, 2), M4_PRIOR, onset=date(2008, 1, 1)) + month = date(2008, 4, 1) + years = history(person, month, {**M4_ANNUAL, 2008: 2}) + result = _computed(person, years, month) + assert result.disability.qualifying_quarter == date(2008, 4, 1) + assert result.disability.upper_qualifying_quarter == date(2008, 1, 1) + # The result names the fact the record leaves open. + assert result.unknown_facts == ("prior_disability_period_basis",) + assert result.decided_despite_unknowns + + +def test_a_prior_basis_split_widens_the_count(): + person = _person(date(1955, 2, 2), M4_PRIOR, onset=date(2008, 1, 1)) + month = date(2008, 1, 1) + annual = { + **{y: 4 for y in (*range(1980, 1985), *range(1989, 1993))}, + **{y: 4 for y in range(1999, 2004)}, + 1993: 3, + 1998: 1, + } + result = _computed(person, history(person, month, annual), month) + assert result.disability.insured + assert ( + result.disability.qc_count_lower, + result.disability.qc_count_upper, + ) == (20, 21) + assert result.unknown_facts == ("prior_disability_period_basis",) + + +def test_a_split_start_names_the_listed_prior(): + # Established, the same split moves the period's start, and the detail + # names the prior that decides it. + person = _person( + date(1968, 2, 2), M4_PRIOR, onset=date(2008, 1, 1), established=True + ) + month = date(2008, 4, 1) + years = history(person, month, {**M4_ANNUAL, 2008: 2}) + detail = _refused(Reason.ASSIGNMENT_COMPLEXITY, person, years, month) + assert detail == LISTED_PRIOR + + +# UNKNOWN priors. + + +def test_unknown_priors_reach_the_onset_quarter(): + # Plain arithmetic: with no prior, 2007Q2 first holds 20 of 40. A prior + # 1990-01-01 to 1999-12-31 begins on 404.130(b) with 20 QCs in 1985 to + # 1989 and lets the 40 counted quarters ending 2007Q1 hold 30. + onset = date(2007, 1, 1) + month = date(2008, 10, 1) + annual = { + **{y: 4 for y in range(1985, 1990)}, + **{y: 3 for y in range(2000, 2006)}, + 2007: 4, + 2008: 4, + } + unknown = _person( + date(1961, 2, 2), + onset=onset, + prior_disability_periods_provenance=UNKNOWN, + ) + years = history(unknown, month, annual) + found = _computed(unknown, years, month, test=DISABILITY).disability + completions = [ + _computed( + _person(date(1961, 2, 2), *priors, onset=onset), + years, + month, + test=DISABILITY, + ).disability.qualifying_quarter + for priors in ( + (), + (i.DisabilityPeriod(date(1990, 1, 1), date(1999, 12, 31)),), + ) + ] + assert completions == [date(2007, 4, 1), date(2007, 1, 1)] + assert (found.upper_qualifying_quarter, found.qualifying_quarter) == ( + date(2007, 1, 1), + date(2007, 4, 1), + ) + + +def test_unknown_priors_may_end_before_a_later_onset_in_its_quarter(): + # A prior can end at a month's end, so a February or March onset can + # follow one in its own quarter; a January 15 onset can't. + for onset, invalid in ( + (date(2022, 1, 15), True), + (date(2022, 2, 15), False), + (date(2022, 3, 15), False), + ): + person = _ended( + date(1993, 2, 2), + onset, + date(2022, 12, 31), + prior_disability_periods_provenance=UNKNOWN, + ) + month = date(2023, 1, 1) + years = history(person, month, {2016: 4, 2017: 2}) + if invalid: + with pytest.raises(i.InvalidFamilyInput, match="no possible"): + i.insured_status(person, years, month, test=FULLY) + else: + _refused(Reason.UNKNOWN_PERIODS, person, years, month, test=FULLY) + + +# A man's elapsed years. + + +def _table_404_115(): + text = source_text("ecfr_20cfr404_subpart_b") + table = text[ + text.index("§ 404.115 Table") : text.index("1 Number of QCs required") + ] + return { + int(match[1]): tuple(int(n) for n in match[2].split()) + for match in re.finditer( + r"Jan\. 2, (\d{4}) to Jan\. 1, \d{4}((?: \d+)+)", table + ) + } + + +def test_the_404_115_table_gives_each_cohort_its_count(): + # Column II for a living worker, by sex; columns III and IV for a death + # before retirement age by year, born before 1930; column V by age at + # death, born 1930 or later. + table = _table_404_115() + assert sorted(table) == list(range(1893, 1929)) + deaths = 0 + for year, numbers in table.items(): + for sex, expected in ((MALE, numbers[0]), (FEMALE, numbers[1])): + person = _person(date(year, 7, 1), sex=sex) + for age in (62, 63, 64, 66): + month = date(year + age, 12, 1) + assert i.fully_insured_requirement(person, month) == expected + if len(numbers) != 5: + continue + death_year, required, age = numbers[2:] + for birth, died in ( + (date(1929, 7, 1), date(death_year, 6, 30)), + (date(1940, 7, 1), date(1940 + age, 6, 30)), + ): + person = _person(birth, death_date=died) + month = date(died.year, 12, 1) + assert i.fully_insured_requirement(person, month) == required + deaths += 1 + # The 33 rows for 1893 through 1925 carry the death columns. + assert deaths == 2 * 33 + + +def test_a_man_who_reached_62_before_1973_counts_to_65(): + # 404.110(b)(2)(iv): he became 62 in 1970, so 1951 to 1972 elapse, and + # 20 QCs fall two short, with or without an RIB month. A death in 1971 + # ends the count at 1970 (404.110(b)(3)). + month = date(1971, 12, 1) + for changes in ({}, {"rib_entitlement_month": date(1971, 12, 1)}): + person = _person(date(1908, 7, 1), sex=MALE, **changes) + years = history(person, month, {y: 1 for y in range(1951, 1971)}) + fully = _computed(person, years, month, test=FULLY).fully + assert (fully.insured, fully.qc_count_lower, fully.required) == ( + False, + 20, + 22, + ) + person = _person(date(1908, 7, 1), sex=MALE, death_date=date(1971, 6, 15)) + years = history(person, month, {y: 1 for y in range(1951, 1971)}) + fully = _computed(person, years, month, test=FULLY).fully + assert (fully.insured, fully.required) == (True, 20) + # 404.110(b)(2)(iii): he became 62 in 1974, so 1951 to 1974 elapse. + person = _person(date(1912, 7, 1), sex=MALE) + month = date(1974, 12, 1) + years = history(person, month, {y: 1 for y in range(1951, 1974)}) + fully = _computed(person, years, month, test=FULLY).fully + assert (fully.insured, fully.qc_count_lower, fully.required) == ( + False, + 23, + 24, + ) + + +# A flagged prior needs one placement for both halves. + + +def test_a_flagged_prior_needs_paragraph_c_without_paragraph_b(): + # Plain arithmetic: she attains 21 in 1983Q2, so 404.130(c) at 1990Q2 + # counts 28 quarters and asks 14, and every placement reaches at most 11. + # 404.130(b) holds on some placements, but none passes 404.130(c) alone. + prior = i.DisabilityPeriod( + date(1990, 4, 1), date(1990, 6, 30), special_insured=True + ) + annual = { + 1980: 3, + 1981: 4, + 1982: 2, + 1983: 3, + 1986: 4, + 1987: 4, + 1990: 1, + 2005: 4, + 2006: 4, + 2007: 4, + 2010: 4, + 2011: 4, + } + month = date(2011, 10, 1) + for established in (True, False, None): + person = _person( + date(1962, 6, 28), + prior, + onset=date(2010, 2, 10), + established=established, + current_disability_period_provenance=( + UNKNOWN if established is None else OBSERVED + ), + ) + detail = _refused( + Reason.ASSIGNMENT_COMPLEXITY, + person, + history(person, month, annual), + month, + ) + assert detail == UNSUPPORTED_PRIOR + + +@pytest.mark.parametrize( + "qcs_2004,test,outcome,detail", + ( + (None, ALL, Reason.UNKNOWN_EARNINGS, None), + (None, FULLY, Reason.ASSIGNMENT_COMPLEXITY, LISTED_PRIOR), + (0, ALL, Reason.ASSIGNMENT_COMPLEXITY, UNSUPPORTED_PRIOR), + (1, ALL, Reason.ASSIGNMENT_COMPLEXITY, UNSUPPORTED_PRIOR), + (2, ALL, None, None), + (3, ALL, None, None), + (4, ALL, Reason.ASSIGNMENT_COMPLEXITY, UNSUPPORTED_PRIOR), + ), +) +def test_only_a_middle_completion_fits_a_flag(qcs_2004, test, outcome, detail): + # Plain arithmetic: at 2006Q1, 404.130(c) counts the 20 quarters from + # 2001Q2 and asks ten, so 2004 needs two QCs beside 2002 and 2003's + # eight. 404.130(b) finds 16 more from 1998 and 1999, so four 2004 QCs + # reach 20 of 40. Only two or three fit the flag. UNKNOWN, the two give + # different dates; FULLY alone holds on both, and the open year still + # decides where the prior begins, which neither bound shows. + prior = i.DisabilityPeriod( + date(2006, 1, 1), date(2006, 12, 31), special_insured=True + ) + person = _person(date(1980, 2, 2), prior) + month = date(2008, 1, 1) + years = history(person, month, {1998: 4, 1999: 4, 2002: 4, 2003: 4}) + years[2004] = ( + i.CoverageYear(UNKNOWN) + if qcs_2004 is None + else i.CoverageYear(OBSERVED, qc_count=qcs_2004) + ) + if outcome is None: + _computed(person, years, month, test=test) + return + found = _refused(outcome, person, years, month, test=test) + assert detail is None or found == detail + + +@pytest.mark.parametrize("unknown_years", (5, 6)) +def test_a_flag_every_completion_contradicts_refuses_by_that_name( + unknown_years, +): + # Plain arithmetic: 1999 to 2003's 20 QCs fill 20 of the 40 quarters + # ending 2004Q1 on every placement, so 404.130(b) held there whatever the + # UNKNOWN years before 1999 hold, and no completion fits the flag. Six + # such years have 15,625 completions, and the refusal still names the + # flag rather than their number. + prior = i.DisabilityPeriod( + date(2004, 1, 1), date(2005, 12, 31), special_insured=True + ) + person = _person(date(1975, 2, 2), prior) + month = date(2007, 1, 1) + years = history(person, month, {y: 4 for y in range(1999, 2004)}) + for year in range(1999 - unknown_years, 1999): + years[year] = i.CoverageYear(UNKNOWN) + detail = _refused(Reason.ASSIGNMENT_COMPLEXITY, person, years, month) + assert detail == UNSUPPORTED_PRIOR + + +# A listed prior no completion supports refuses first. + + +@pytest.mark.parametrize("fill", (None, 0, 4)) +def test_an_unsupported_prior_refuses_before_unknown_earnings(fill): + # Plain arithmetic: born 1940, she can reach 20 of 40 at 1970Q1 only with + # QCs before 1968, and the record declares none; past blindness counts + # only from 1973. No completion of 1974 to 1977 can begin the prior. + person = _ended( + date(1940, 2, 2), + date(1977, 2, 15), + date(1977, 4, 30), + i.DisabilityPeriod(date(1970, 1, 1), date(1977, 1, 31)), + ) + month = date(1978, 1, 1) + years = history(person, month, {1968: 4, 1969: 4}) + for year in range(1974, 1978): + years[year] = ( + i.CoverageYear(UNKNOWN) + if fill is None + else i.CoverageYear( + OBSERVED, qc_quarters=tuple(n < fill for n in range(4)) + ) + ) + detail = _refused(Reason.ASSIGNMENT_COMPLEXITY, person, years, month) + assert detail == UNSUPPORTED_PRIOR + + +@pytest.mark.parametrize( + "start,supported", + ((date(1972, 12, 1), False), (date(1973, 1, 1), True)), +) +def test_past_blindness_begins_a_prior_only_from_1973(start, supported): + # RS00301.150 A dates blindness with fully insured status alone from + # benefits payable January 1973. Born 1940, she was 31 in 1971, and her + # 12 QCs from 1962 to 1964 make her fully insured in 1972 or 1973 (10 or + # 11 elapsed years) but never give 20 of 40 there. + person = _person( + date(1940, 2, 2), i.DisabilityPeriod(start, date(1973, 12, 31)) + ) + month = date(1980, 1, 1) + years = history(person, month, {1962: 4, 1963: 4, 1964: 4}) + if supported: + result = _computed(person, years, month) + fully = result.fully + assert (fully.insured, fully.qc_count_lower, fully.required) == ( + False, + 12, + 17, + ) + assert _dli(result) == (date(1967, 6, 30), date(1967, 6, 30), False) + return + detail = _refused(Reason.ASSIGNMENT_COMPLEXITY, person, years, month) + assert detail == UNSUPPORTED_PRIOR + + +@pytest.mark.parametrize("test", (FULLY, ALL)) +def test_a_1965_prior_cannot_rest_on_past_blindness(test): + # Born 1930, her 16 QCs from 1952 to 1955 make her fully insured in 1965 + # (13 elapsed years) but leave 3 QCs in the 40 quarters ending 1965Q1. + person = _person( + date(1930, 2, 2), + i.DisabilityPeriod(date(1965, 1, 1), date(1966, 12, 31)), + ) + month = date(1980, 1, 1) + years = history(person, month, {y: 4 for y in range(1952, 1956)}) + detail = _refused( + Reason.ASSIGNMENT_COMPLEXITY, person, years, month, test=test + ) + assert detail == UNSUPPORTED_PRIOR + + +# Listed priors before 1956. + +PRE1956_PRIOR = i.DisabilityPeriod(date(1952, 7, 15), date(1958, 12, 31)) +PRE1956_BASE = {1938: 4, 1939: 4, 1940: 4, 1941: 2, 1951: 4, 1952: 2} + + +@pytest.mark.parametrize( + "later,reason,detail", + ( + ( + {1953: 4, 1954: 4, 1955: 4, 1956: 4}, + Reason.ASSIGNMENT_COMPLEXITY, + UNSUPPORTED_PRIOR, + ), + ( + {1953: 4, 1954: 4, 1959: 4, 1960: 3}, + Reason.DISABILITY_BEFORE_1956, + "RS00301.480 may have begun a listed prior before 1956", + ), + ({1961: 4, 1962: 4}, None, None), + ), +) +def test_a_pre1956_listed_prior_rests_on_rs00301_480(later, reason, detail): + # RS00301.480 B.1: the 20 QCs through 1952Q2 include six continuous from + # 1951Q1. 20 of 40 inside the prior, at 1956Q2, excludes the route on + # both readings of A; 20 of 40 at 1960Q2, after it, excludes it on one; + # none before October 1960 leaves it. + person = _person(date(1910, 2, 2), PRE1956_PRIOR, sex=MALE) + month = date(1968, 1, 1) + years = history(person, month, {**PRE1956_BASE, **later}) + if reason is None: + result = _computed(person, years, month) + assert result.fully.insured + assert not result.disability.insured + return + assert _refused(reason, person, years, month) == detail + + +def test_a_listed_alternate_prior_lets_a_later_period_begin(): + # The current period begins in 1964 on 404.130(b), after a prior that + # B.1 alone began in 1952. + person, _, month = _pre1956_case() + onset = date(1964, 7, 15) + annual = { + **PRE1956_BASE, + 1961: 4, + 1962: 4, + 1963: 4, + 1964: 2, + } + for end in (1959, 1960): + listed = _person( + person.birth_date, + i.DisabilityPeriod(date(1952, 7, 15), date(end, 12, 31)), + onset=onset, + established=True, + ) + years = history(listed, month, annual) + result = _computed(listed, years, month, test=FULLY) + assert result.current_disability_period_start == onset + for annual, end in ( + ( + { + 1938: 4, + 1939: 4, + 1940: 4, + 1941: 2, + 1961: 4, + 1962: 4, + 1963: 4, + 1964: 2, + }, + 1959, + ), + ( + { + 1938: 4, + 1939: 4, + 1940: 4, + 1941: 2, + **{y: 4 for y in range(1955, 1964)}, + 1964: 2, + }, + 1954, + ), + ): + listed = _person( + person.birth_date, + i.DisabilityPeriod(date(1952, 7, 15), date(end, 12, 31)), + onset=onset, + established=True, + ) + years = history(listed, month, annual) + detail = _refused( + Reason.ASSIGNMENT_COMPLEXITY, listed, years, month, test=FULLY + ) + assert detail == UNSUPPORTED_PRIOR + + +# Published first onsets. + + +def _patterned(person, month, patterns): + years = history(person, month) + for year, pattern in patterns.items(): + flags = tuple(letter == "C" for letter in pattern) + years[year] = i.CoverageYear( + OBSERVED, + **( + {"qc_quarters": flags} + if year < 1978 + else {"qc_count": sum(flags)} + ), + ) + return years + + +@pytest.mark.parametrize( + "source,quote,birth,onset,patterns,counts", + ( + ( + "poms_rs_00301_140", + "There are 14 QTRS elapsing after the QTR of age 21 up to and " + "including onset date. Joseph requires and has 7 QC's", + date(1956, 9, 16), + date(1981, 2, 3), + {1978: "CCNN", 1979: "CCCN", 1980: "CCCC", 1981: "NNNN"}, + (14, 7, 9), + ), + ( + "poms_rs_00301_140", + "Jane requires and has 6 QC's to be insured for DIB.", + date(1967, 3, 16), + date(1988, 3, 29), + {1986: "CCCN", 1987: "CCCN", 1988: "NNNN"}, + (12, 6, 6), + ), + ( + "poms_rs_00301_140", + "Ralph requires and has 6 QC's to be insured for DIB.", + date(1967, 4, 12), + date(1988, 2, 16), + {1986: "CNNN", 1987: "CCCC", 1988: "CNNN"}, + (12, 6, 6), + ), + ( + "poms_rs_00301_140", + "Sam requires and has 6 QC's to be insured for DIB.", + date(1964, 2, 16), + date(1985, 12, 16), + {1983: "CCNN", 1984: "CCCC", 1985: "NNNN"}, + (12, 6, 6), + ), + ( + "poms_rs_00301_147", + "Mary required 8 QCs to meet the special insured status earnings " + "test. Mary had 8 QC's during that period", + date(1950, 4, 16), + date(1975, 5, 16), + { + 1970: "NNNC", + 1971: "NNCC", + 1972: "CCCN", + 1973: "CNNC", + 1974: "NNCC", + 1975: "NNNN", + }, + (16, 8, 9), + ), + ( + "poms_rs_00301_147", + "John required 13 QC's to meet the special insured status " + "earnings test. Since John had 13 QC's during this period", + date(1940, 7, 16), + date(1968, 3, 4), + { + 1961: "NNNC", + 1962: "NCCN", + 1963: "NNCC", + 1964: "CCNC", + 1965: "NNNN", + 1966: "CCNN", + 1967: "CNCC", + 1968: "NNNN", + }, + (26, 13, 13), + ), + ( + "poms_rs_00301_147", + "There were 17 QTRs elapsing after the QTR of attainment of age " + "21 up to and including the QTR of onset, Frank required 8 QC's", + date(1945, 7, 14), + date(1970, 12, 13), + { + 1966: "NNNN", + 1967: "CNCN", + 1968: "NNCC", + 1969: "NNNC", + 1970: "CCCN", + }, + (17, 8, 8), + ), + ), + ids=( + "rs140-joseph-6", + "rs140-jane-7", + "rs140-ralph-8", + "rs140-sam-9", + "rs147-mary-1", + "rs147-john-2", + "rs147-frank-3", + ), +) +def test_each_published_first_onset_reproduces( + source, quote, birth, onset, patterns, counts +): + # Each example's first onset, before any prior period: the quarters + # counted, the QCs required and the QCs the printed pattern puts there. + # Joseph "requires and has 7" of the nine his pattern holds. Mary "had 8 + # QC's", but her pattern holds nine (1971Q3-Q4, 1972Q1-Q3, 1973Q1 and + # Q4, 1974Q3-Q4), a slip the example registry logs. + assert quote in source_text(source) + person = _person(birth, onset=onset) + month = onset.replace(day=1) + years = _patterned(person, month, patterns) + found = _computed(person, years, month, test=DISABILITY).disability + assert found.insured + assert found.rule == "under31_special" + assert (len(found.window), found.required, found.qc_count_lower) == counts + + +# Lows. + + +def test_declared_dates_past_the_statutory_end_are_input_errors(): + # 404.321(b) ends a period by the month before FRA, June 2016 for a + # birth in June 1950. + for end, valid in ( + (date(2016, 5, 31), True), + (date(2016, 6, 30), False), + (date(2017, 12, 31), False), + ): + if valid: + _ended(date(1950, 6, 15), date(2010, 1, 15), end) + continue + with pytest.raises(i.InvalidFamilyInput, match="statutory FRA end"): + _ended(date(1950, 6, 15), date(2010, 1, 15), end) + + +@pytest.mark.parametrize( + "field,month,message", + ( + ("dib_entitlement_month", date(2005, 7, 1), None), + ("dib_entitlement_month", date(2005, 8, 1), "at or after FRA"), + ("dib_entitlement_month", date(2010, 1, 1), "at or after FRA"), + ("rib_entitlement_month", date(2002, 2, 1), None), + ("rib_entitlement_month", date(2002, 1, 1), "before age 62"), + ("rib_entitlement_month", date(1964, 3, 1), "before age 62"), + ), +) +def test_entitlement_months_must_be_possible(field, month, message): + # Born 1940-02-02, FRA arrives in August 2005 and 62 on 2002-02-01. + if message is None: + assert getattr(_person(date(1940, 2, 2), **{field: month}), field) + return + with pytest.raises(i.InvalidFamilyInput, match=message): + _person(date(1940, 2, 2), **{field: month}) + + +def test_the_pre_1983_refusal_needs_31_before_may_1983(): + # 404.130(c) decides a second onset before 31 under pre-1983 law too, so + # the rule refuses only a holder whose age-31 quarter begins before May + # 1983. + person = _person( + date(1956, 9, 16), + i.DisabilityPeriod( + date(1978, 10, 2), date(1979, 12, 31), special_insured=True + ), + onset=date(1982, 3, 1), + ) + month = date(1982, 3, 1) + years = history( + person, month, {1976: 4, 1977: 4, 1978: 3, 1980: 2, 1981: 4} + ) + result = _computed(person, years, month) + assert result.disability.rule == "under31_special" + person = _person( + date(1950, 1, 2), + i.DisabilityPeriod( + date(1975, 1, 1), date(1976, 12, 31), special_insured=True + ), + onset=date(1982, 6, 1), + ) + month = date(1982, 6, 1) + years = history( + person, + month, + {y: 4 for y in (*range(1971, 1975), *range(1977, 1982))}, + ) + _refused(Reason.HISTORICAL_SUBSEQUENT, person, years, month) + + +def test_the_requirement_helper_checks_what_insured_status_checks(): + person = _person(date(1960, 2, 2), dib_entitlement_month=date(2006, 1, 1)) + for call in ( + lambda: i.fully_insured_requirement(person, date(2005, 1, 1)), + lambda: i.insured_status( + person, + history(person, date(2005, 1, 1)), + date(2005, 1, 1), + ), + ): + with pytest.raises(i.InvalidFamilyInput, match="follows query"): + call() + with pytest.raises(i.InvalidFamilyInput, match="outside"): + i.fully_insured_requirement( + _person(date(1960, 2, 2)), date(1959, 1, 1) + ) + + +def test_wages_paid_after_death_count_toward_the_year(): + # Act 213(a)(2)(B): no quarter after the death quarter is a QC, but the + # $7,770 paid in 1968Q2 brings the year to the $7,800 maximum, so 1968Q1 + # becomes a QC though it holds $30. + person = _person(date(1930, 2, 2), death_date=date(1968, 2, 15)) + month = date(1970, 1, 1) + found = [] + for wages in ((30, 7770, 0, 0), (30, 0, 0, 0), (7700, 100, 0, 0)): + years = history(person, month, {y: 4 for y in range(1950, 1968)}) + years[1968] = i.CoverageYear( + OBSERVED, quarterly_wages=tuple(Fraction(w) for w in wages) + ) + found.append( + _computed(person, years, month, test=FULLY).qcs_by_year[1968] + ) + assert found == [(1, 1), (0, 0), (1, 1)] + + +@pytest.mark.parametrize( + "year,declared,message", + ( + (1960, (True, False, False, False), "QCs declared before birth"), + (1966, (False, False, False, True), "QCs declared after coverage"), + (1966, (Fraction(0),) * 3 + (Fraction(100),), "earnings declared"), + ), +) +def test_quarterly_bounds_name_themselves(year, declared, message): + person = _person(date(1960, 8, 15)) + exit_month = date(1966, 8, 1) + years = history(person, date(1968, 1, 1), end=exit_month) + years[year] = i.CoverageYear( + OBSERVED, + **( + {"qc_quarters": declared} + if isinstance(declared[0], bool) + else {"quarterly_wages": declared} + ), + ) + with pytest.raises(i.InvalidFamilyInput, match=message): + i.insured_status( + person, years, date(1968, 1, 1), coverage_end_month=exit_month + ) + # The exit quarter itself takes a flag. + years[1966] = i.CoverageYear( + OBSERVED, qc_quarters=(False, False, True, False) + ) + years[1960] = i.CoverageYear(OBSERVED, qc_quarters=(False,) * 4) + result = i.insured_status( + person, + years, + date(1968, 1, 1), + test=FULLY, + coverage_end_month=exit_month, + ) + assert result.fully.qc_count_lower == 1 + + +# The design note's evidence. + + +def test_the_note_cites_only_tests_that_exist(): + # The note names tests as its evidence, so each must still run, and it + # cites no uncommitted scratch file. + tests = Path(__file__).resolve().parent + note = (tests.parent / "docs/design/track_b_insured_status.md").read_text() + defined = set() + for module in tests.rglob("*.py"): + defined.add(module.stem) + defined.update( + re.findall(r"^\s*def (test_\w+)", module.read_text(), re.M) + ) + assert sorted(set(re.findall(r"`(test_\w+)", note)) - defined) == [] + assert "scratch/" not in note diff --git a/tests/test_track_b_insured_status_fix_round_4_routes.py b/tests/test_track_b_insured_status_fix_round_4_routes.py index 42fd98db1..01e163c6a 100644 --- a/tests/test_track_b_insured_status_fix_round_4_routes.py +++ b/tests/test_track_b_insured_status_fix_round_4_routes.py @@ -80,7 +80,7 @@ def _declared_end_unknown_earnings_case(*, first=2, ending=date(2022, 3, 31)): return person, years, month -def _prior_overlap_unknown_earnings_case(*, missing_year=1971): +def _shared_quarter_unknown_earnings_case(*, missing_year=1971): person = i.Person( date(1910, 2, 2), sex=i.Sex.FEMALE, @@ -194,11 +194,14 @@ def test_possible_unknown_earnings_filling_prevents_declared_end_input_error( ) -def test_unknown_earnings_can_avoid_derived_prior_quarter_overlap(): - person, years, month = _prior_overlap_unknown_earnings_case() +def test_unknown_onset_year_earnings_decide_the_current_start(): + person, years, month = _shared_quarter_unknown_earnings_case() with pytest.raises(i.InsuredConfigurationUnsupported) as error: i.insured_status(person, years, month, test=i.InsuredTest.FULLY) assert error.value.reason is i.InsuredUnsupportedReason.UNKNOWN_EARNINGS + assert error.value.detail == ( + "Unknown earnings decide established current period start" + ) _retained_row( person, years, @@ -211,36 +214,31 @@ def test_unknown_earnings_can_avoid_derived_prior_quarter_overlap(): @settings(max_examples=4, deadline=None) @example(missing_year=1971) @given(missing_year=st.integers(1968, 1971)) -def test_possible_lower_earnings_filling_prevents_upper_overlap_input_error( - missing_year, -): - """An invalid upper-credit period cannot disprove every completion. +def test_every_onset_year_filling_starts_a_valid_period(missing_year): + """Each 1972 filling starts the period, and the UNKNOWN year moves it. The declared prior start meets the captured pre1956 alternate test. - Zero 1972 QCs yields an insured new start in 1973Q1. More 1972 QCs - move that start into the prior ending quarter, which the interface's - nonoverlapping-quarter representation rejects for that completion. + Zero 1972 QCs start the new period in 1973Q1. Any 1972 QC insures the + onset quarter, which the prior left in January, so the period starts + on the onset day (20 CFR 404.321(a)); a period may begin in the quarter + a prior ended (RS 00301.140 example 7). Round 4 rejected those fillings + as overlapping the prior's last quarter. """ - person, years, month = _prior_overlap_unknown_earnings_case( + person, years, month = _shared_quarter_unknown_earnings_case( missing_year=missing_year ) - concrete_validity = [] + starts = [] for count in range(5): concrete = dict(years) concrete[1972] = i.CoverageYear( OBSERVED, qc_quarters=tuple(n < count for n in range(4)) ) - try: - result = i.insured_status( - person, concrete, month, test=i.InsuredTest.FULLY - ) - except i.InvalidFamilyInput: - concrete_validity.append(False) - else: - concrete_validity.append(True) - assert result.fully.insured - assert result.current_disability_period_start == date(1973, 1, 1) - assert concrete_validity == [True, False, False, False, False] + result = i.insured_status( + person, concrete, month, test=i.InsuredTest.FULLY + ) + assert result.fully.insured + starts.append(result.current_disability_period_start) + assert starts == [date(1973, 1, 1)] + [date(1972, 2, 15)] * 4 _retained_row( person, years, diff --git a/tests/test_track_b_insured_status_fix_round_5_possibility.py b/tests/test_track_b_insured_status_fix_round_5_possibility.py index 057bf39e1..e7dc70bd3 100644 --- a/tests/test_track_b_insured_status_fix_round_5_possibility.py +++ b/tests/test_track_b_insured_status_fix_round_5_possibility.py @@ -18,7 +18,7 @@ from tests.test_track_b_insured_status import declared, history from tests.test_track_b_insured_status_fix_round_4_routes import ( _pre1956_case, - _prior_overlap_unknown_earnings_case, + _shared_quarter_unknown_earnings_case, _short_period_case, ) @@ -167,11 +167,11 @@ def test_unknown_declaration_exactly_matches_all_concrete_qc_fillings( ), prior_ends_in_onset_quarter=st.booleans(), ) -def test_overlap_declaration_exactly_matches_every_quarter_filling( +def test_shared_quarter_declaration_exactly_matches_every_quarter_filling( missing_year, ending, prior_ends_in_onset_quarter ): - """A single filling must satisfy the fixed end and derived overlap.""" - person, years, month = _prior_overlap_unknown_earnings_case( + """One filling must insure a start that the fixed end allows.""" + person, years, month = _shared_quarter_unknown_earnings_case( missing_year=missing_year ) prior = person.prior_disability_periods[0] @@ -186,26 +186,43 @@ def test_overlap_declaration_exactly_matches_every_quarter_filling( assert len(_assert_exact_classification(person, years, month)) == 16 -def test_different_fillings_cannot_separately_satisfy_end_and_overlap(): - person, years, month = _prior_overlap_unknown_earnings_case() +def test_an_april_end_needs_the_onset_quarter_insured(): + """Only a 1972Q1 QC insures a quarter before the February recovery. + + The April 1972 end puts recovery in February (404.321(b)), so the + period needs an insured quarter that begins by then, 1972Q1. That is + the quarter the prior ended in January, which the period may share + (RS 00301.140 example 7), and only a 1972Q1 QC insures it. The masks + run Q1 first, so the last eight fillings credit Q1. Round 5 rejected + every filling, because a 1972Q1 start overlapped the prior's last + quarter. + """ + person, years, month = _shared_quarter_unknown_earnings_case() person = replace( person, current_disability_period_end=date(1972, 4, 30), current_disability_period_end_provenance=OBSERVED, ) valid = _assert_exact_classification(person, years, month) - assert valid == [False] * 16 + assert valid == [False] * 8 + [True] * 8 + +def test_any_1972_qc_starts_a_period_before_a_december_end(): + """A December 1972 end puts recovery in October (404.321(b)). -def test_later_quarter_filling_can_clear_overlap_before_fixed_end(): - person, years, month = _prior_overlap_unknown_earnings_case() + A QC in any 1972 quarter insures a quarter that begins by then, so + only the all-zero filling fails. Round 5 also rejected the eight + fillings with a 1972Q1 QC, which start the period on the onset day in + the quarter the prior ended. + """ + person, years, month = _shared_quarter_unknown_earnings_case() person = replace( person, current_disability_period_end=date(1972, 12, 31), current_disability_period_end_provenance=OBSERVED, ) valid = _assert_exact_classification(person, years, month) - assert valid == [False] + [True] * 7 + [False] * 8 + assert valid == [False] + [True] * 15 @pytest.mark.parametrize("condition", [None, *i.CoverageCondition]) @@ -369,8 +386,13 @@ def test_exact_classification_keeps_short_dib_entitled_prior_filling(): assert _classification(person, years, month) == any(concrete) -def test_large_unresolved_overlap_has_explicit_complexity_refusal(): - person, years, month = _prior_overlap_unknown_earnings_case() +def test_many_unknown_years_keep_one_earnings_refusal_row(): + """Seven UNKNOWN years keep the earnings refusal and one row. + + Round 5 refused this record as more than 4096 overlap fillings. A + period may share the quarter a prior ended, so no such search runs. + """ + person, years, month = _shared_quarter_unknown_earnings_case() person = replace( person, current_disability_period_end=date(1972, 12, 31), @@ -386,10 +408,11 @@ def test_large_unresolved_overlap_has_explicit_complexity_refusal(): ), ) assert ( - row.unsupported.reason - is i.InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY + row.unsupported.reason is i.InsuredUnsupportedReason.UNKNOWN_EARNINGS + ) + assert row.unsupported.detail == ( + "Unknown earnings decide a valid established current period" ) - assert "overlap fillings" in row.unsupported.detail assert count_family_outcomes((row,)).rows == 1 diff --git a/tests/test_track_b_insured_status_fix_round_6_ordering.py b/tests/test_track_b_insured_status_fix_round_6_ordering.py index f015242b6..9824784b3 100644 --- a/tests/test_track_b_insured_status_fix_round_6_ordering.py +++ b/tests/test_track_b_insured_status_fix_round_6_ordering.py @@ -16,7 +16,7 @@ from populace_dynamics.track_b.gross_benefits import count_family_outcomes from tests.test_track_b_insured_status import declared, history from tests.test_track_b_insured_status_fix_round_4_routes import ( - _prior_overlap_unknown_earnings_case, + _shared_quarter_unknown_earnings_case, ) from tests.test_track_b_insured_status_fix_round_5_possibility import ( _classification, @@ -196,8 +196,8 @@ def test_deferred_refusals_keep_original_sorted_year_priority(reverse): assert row.unsupported.detail == "1937_earnings_allocation_unsupported" -def test_unresolved_overlap_keeps_original_deferred_refusal(): - person, years, month = _prior_overlap_unknown_earnings_case() +def test_many_unknown_years_keep_original_deferred_refusal(): + person, years, month = _shared_quarter_unknown_earnings_case() person = replace( person, current_disability_period_end=date(1972, 12, 31), @@ -213,7 +213,7 @@ def test_unresolved_overlap_keeps_original_deferred_refusal(): @settings(max_examples=4, deadline=None) @given(fixed_first=st.booleans(), reverse=st.booleans()) -def test_deferred_quarter_fillings_keep_fixed_minimum_and_valid_middle( +def test_deferred_quarter_fillings_survive_a_shared_onset_quarter( fixed_first, reverse ): person = i.Person( @@ -245,9 +245,12 @@ def test_deferred_quarter_fillings_keep_fixed_minimum_and_valid_middle( }, ) # The supplied prior has the captured alternate's 20 total QCs and - # all six continuous 1951 Q1--1952 Q2 credits. For the current onset, - # Removing prior-period gaps opens the alternate for 0000 too. All - # eight Q1-uncredited fillings remain possible; credited Q1 overlaps. + # all six continuous 1951 Q1--1952 Q2 credits. Removing prior-period + # gaps opens the alternate for the current onset under 0000 too. A + # credited 1954Q1 starts the period on the onset day, in the quarter the + # prior ended in January (RS 00301.140 example 7), so every filling + # keeps a row, each with a named pre1956 refusal. Round 6 rejected the + # eight Q1-credited fillings as overlapping the prior's last quarter. flags = [ flags for flags in product((False, True), repeat=4) @@ -261,7 +264,7 @@ def test_deferred_quarter_fillings_keep_fixed_minimum_and_valid_middle( ) for f in flags ] - assert valid == ([False] * 8 if fixed_first else [True] * 8 + [False] * 8) + assert valid == [True] * len(flags) years[1954] = i.CoverageYear( OBSERVED, agricultural_wages=Fraction(100), @@ -270,15 +273,12 @@ def test_deferred_quarter_fillings_keep_fixed_minimum_and_valid_middle( ) if reverse: years = dict(reversed(tuple(years.items()))) - if any(valid): - row = _evaluate(person, years, month) - assert ( - row.unsupported.reason - is i.InsuredUnsupportedReason.PRE1955_AGRICULTURE - ) - assert count_family_outcomes((row,)).weight == Fraction(3, 2) - else: - _no_row(person, years, month) + row = _evaluate(person, years, month) + assert ( + row.unsupported.reason + is i.InsuredUnsupportedReason.PRE1955_AGRICULTURE + ) + assert count_family_outcomes((row,)).weight == Fraction(3, 2) @pytest.mark.parametrize("year,values,reason", EARLY) diff --git a/tests/test_track_b_insured_status_fix_round_6_routes.py b/tests/test_track_b_insured_status_fix_round_6_routes.py index e83fadb90..bbdce6a89 100644 --- a/tests/test_track_b_insured_status_fix_round_6_routes.py +++ b/tests/test_track_b_insured_status_fix_round_6_routes.py @@ -220,12 +220,19 @@ def test_excluding_alternate_preserves_possible_nonempty_prior_history(): assert row.result.fully.insured -def _immutable_overlap_case(): +def _shared_end_quarter_case(prior_end=date(1977, 1, 31)): + # Fully insured in 1973Q1 (12 QCs for 11 elapsed years) and short of + # 20 of 40, the prior rests on past blindness (404.130(e), from January + # 1973 under RS 00301.150 A). The April end puts recovery in February + # (404.321(b)), so only 1977Q1, the quarter the prior ended in January, + # can start the period (RS 00301.140 example 7). There 20 of 40 needs + # the prior disregarded (404.130(f)) and every 1974-1977Q1 quarter + # credited, which UNKNOWN 1974-1977 leaves open. person = i.Person( date(1940, 2, 2), disability_onset=date(1977, 2, 15), prior_disability_periods=( - i.DisabilityPeriod(date(1970, 1, 1), date(1977, 1, 31)), + i.DisabilityPeriod(date(1973, 1, 1), prior_end), ), prior_disability_periods_provenance=OBSERVED, current_disability_period_established=True, @@ -236,13 +243,50 @@ def _immutable_overlap_case(): sspa211_provenance=OBSERVED, ) month = date(1978, 1, 1) - years = history(person, month, {1968: 4, 1969: 4}) + years = history(person, month, {1966: 4, 1967: 4, 1968: 4}) years.update({year: i.CoverageYear(UNKNOWN) for year in range(1974, 1978)}) return person, years, month -def test_fixed_same_quarter_overlap_precedes_large_filling_refusal(): - _assert_invalid_without_row(*_immutable_overlap_case()) +def _filled(years, counts): + return { + **years, + **{ + year: i.CoverageYear( + OBSERVED, qc_quarters=tuple(n < count for n in range(4)) + ) + for year, count in zip(range(1974, 1978), counts, strict=True) + }, + } + + +def _assert_earnings_refusal_row(person, years, month): + row = _row(person, years, month) + assert ( + row.unsupported.reason is i.InsuredUnsupportedReason.UNKNOWN_EARNINGS + ) + assert row.unsupported.detail == ( + "Unknown earnings decide a valid established current period" + ) + assert count_family_outcomes((row,)).rows == 1 + + +def test_a_shared_end_quarter_leaves_validity_to_unknown_credits(): + """Round 6 rejected this record: its only start overlapped the prior. + + A period may now begin in the quarter a prior ended, so the credits + decide validity. Every 1974-1977Q1 quarter credited starts the period + on the onset day; one fewer leaves no insured quarter by February. + """ + person, years, month = _shared_end_quarter_case() + _assert_earnings_refusal_row(person, years, month) + result = i.insured_status( + person, _filled(years, (4, 4, 4, 1)), month, test=i.InsuredTest.FULLY + ) + assert result.fully.insured + assert result.current_disability_period_start == date(1977, 2, 15) + for counts in ((0, 0, 0, 0), (4, 4, 4, 0), (3, 4, 4, 1)): + _assert_invalid_without_row(person, _filled(years, counts), month) @settings(max_examples=12, deadline=None) @@ -250,10 +294,11 @@ def test_fixed_same_quarter_overlap_precedes_large_filling_refusal(): ending_month=st.sampled_from([4, 5]), extra_unknown=st.sampled_from([None, 1973, 1978]), ) -def test_immutable_overlap_is_independent_of_credit_uncertainty( +def test_shared_end_quarter_validity_stays_with_unknown_credits( ending_month, extra_unknown ): - person, years, month = _immutable_overlap_case() + """A May end (recovery in March) still leaves only 1977Q1 to start.""" + person, years, month = _shared_end_quarter_case() person = replace( person, current_disability_period_end=date( @@ -262,33 +307,25 @@ def test_immutable_overlap_is_independent_of_credit_uncertainty( ) if extra_unknown is not None: years[extra_unknown] = i.CoverageYear(UNKNOWN) - _assert_invalid_without_row(person, years, month) + _assert_earnings_refusal_row(person, years, month) -def test_large_overlap_neighbour_keeps_valid_filling(): - person, years, month = _immutable_overlap_case() - person = replace( - person, - prior_disability_periods=( - i.DisabilityPeriod(date(1970, 1, 1), date(1976, 12, 31)), - ), - ) - row = _row(person, years, month) - assert ( - row.unsupported.reason is i.InsuredUnsupportedReason.UNKNOWN_EARNINGS - ) - concrete = dict(years) - concrete.update( - { - year: i.CoverageYear(OBSERVED, qc_quarters=(True,) * 4) - for year in range(1974, 1978) - } - ) +@pytest.mark.parametrize("prior_end", [date(1977, 1, 31), date(1976, 12, 31)]) +def test_a_prior_ending_in_the_onset_quarter_classifies_like_one_before( + prior_end, +): + """A January end constrains the start no more than a December one. + + Round 6 kept only the December end valid. Under the disregard that + insures 1977Q1, the two records count the same quarters. + """ + person, years, month = _shared_end_quarter_case(prior_end) + _assert_earnings_refusal_row(person, years, month) result = i.insured_status( - person, concrete, month, test=i.InsuredTest.FULLY + person, _filled(years, (4, 4, 4, 4)), month, test=i.InsuredTest.FULLY ) - assert result.fully.insured assert result.current_disability_period_start == date(1977, 2, 15) + _assert_invalid_without_row(person, _filled(years, (4, 4, 4, 0)), month) @pytest.mark.parametrize("twentieth_quarter", [2, 3]) diff --git a/tests/test_track_b_insured_status_fix_round_8.py b/tests/test_track_b_insured_status_fix_round_8.py index b69f309df..246c149b2 100644 --- a/tests/test_track_b_insured_status_fix_round_8.py +++ b/tests/test_track_b_insured_status_fix_round_8.py @@ -238,6 +238,14 @@ def test_independent_date_oracle_classifies_covered_quarters_both_directions( covered.month, calendar.monthrange(covered.year, covered.month)[1], ) + if covered >= fra_month_start: + # A period ends by the month before FRA (404.321(b)), so a + # later declared end has no lawful filling (round 23). + with pytest.raises( + i.InvalidFamilyInput, match="statutory FRA end" + ): + _case(fra_month=fra_month, end=covered) + covered = fra_month_start - timedelta(days=1) if mode == "unknown": covered = date(1955, 7, 15) else: diff --git a/tests/test_track_b_insured_status_qc.py b/tests/test_track_b_insured_status_qc.py index 9f9c7e7a3..3c1cbb8ed 100644 --- a/tests/test_track_b_insured_status_qc.py +++ b/tests/test_track_b_insured_status_qc.py @@ -270,22 +270,18 @@ def test_disability_exclusion_never_adds_qc(year, start, length, count): ) -def test_death_future_exit_and_disability_endpoint_exclusions(): +def test_death_future_and_disability_endpoint_exclusions(): quarters = qc._year_quarters(2026) assert ( qc._allowed_quarters( - 2026, - through_quarter=quarters[2], - death_quarter=quarters[1], - coverage_end_quarter=quarters[3], + 2026, through_quarter=quarters[2], death_quarter=quarters[1] ) == quarters[:2] ) + # A quarter not yet begun is barred. A coverage exit bars only later + # years, which the history leaves out (round 23). assert ( - qc._allowed_quarters( - 2026, through_quarter=quarters[3], coverage_end_quarter=quarters[0] - ) - == quarters[:1] + qc._allowed_quarters(2026, through_quarter=quarters[0]) == quarters[:1] ) assert qc._allowed_quarters( 2026, diff --git a/tests/test_track_b_insured_status_sources.py b/tests/test_track_b_insured_status_sources.py index 3ae7a1dc3..1afcb24eb 100644 --- a/tests/test_track_b_insured_status_sources.py +++ b/tests/test_track_b_insured_status_sources.py @@ -693,19 +693,28 @@ def test_rs00301_800_exhibit_text_pins_every_linked_attachment(): assert case["coverage"] == "table_differential" -def test_rs00301_800_pdf_footnote_misprints_the_1913_male_age_65_cohort(): - """The PDF's footnote says 1/2/31; its GIF rendering and the CFR say 1913. - - The image rendering (G-RS_00301.800-2.gif, pinned in served_bodies) - prints "born before 1/2/13", and the exhibit's own table splits its male - and female columns at 1913. 20 CFR 404.132(b) ties the male rule to men - born before January 2, 1913. The implementation follows the CFR. +def test_rs00301_800_pdf_footnote_misdates_the_male_age_65_cohort(): + """The PDF's footnote 2 says 1/2/31; 404.110(b)(2) puts the line at 1911. + + 404.110(b)(2)(iv) counts to age 65 only for a man who became 62 before + 1973, born before January 2, 1911, and (iii) counts to 1975 for one born + from then through January 1, 1913. (ii) covers the rest of 1913, and + together they give the exhibit's merged 1910-1913 row of 24 QCs. The + January 2, 1913 date in 20 CFR 404.132(b) belongs to the disability + prerequisite's 1975 cap. The GIF renderings are pinned by hash only; + their text is not captured, so no reading of them is claimed. The + implementation follows 404.110(b)(2). """ assert ( "The determining age for men born before 1/2/31 is age 65." in source_text("poms_rs_00301_800_exhibit") ) assert "1910-1913 1913 1975 24" in source_text("poms_rs_00301_800_exhibit") + assert ( + "(iii) The year 1975, if you are a man who became age 62 in 1973 or " + "1974; or (iv) The year you became age 65, if you are a man who " + "became age 62 before 1973." + ) in source_text("ecfr_20cfr404_subpart_b") assert "If you are a man born before January 2, 1913" in source_text( "ecfr_20cfr404_subpart_b" ) diff --git a/tests/test_track_b_insured_status_status_oracle.py b/tests/test_track_b_insured_status_status_oracle.py index 44bb43b0d..bb4faf7a4 100644 --- a/tests/test_track_b_insured_status_status_oracle.py +++ b/tests/test_track_b_insured_status_status_oracle.py @@ -18,7 +18,9 @@ Act 214(a), 223(c), 20 CFR 404.110(c), 404.130(a),(e),(f), 404.131, 404.143(b), 404.146(d) and 404.321(a) supply the arithmetic. Annual QCs are assigned favorably (RS 00301.230). A lawful filling has its own first -insured start; that start supplies the current period for FULLY and +insured start, on the onset day or the first day of a later quarter, so +the ``shared`` prior, which ends in the onset quarter, never blocks it +(RS 00301.140 example 7). That start supplies the current period for FULLY and CURRENTLY. DISABILITY must qualify without using the period it establishes. Each returned status must equal the favorable Boolean over all lawful fillings. Each exact count, assignment and date last insured must be the best @@ -42,7 +44,7 @@ @dataclass(frozen=True) class Declaration: blind: bool = False - prior: str = "overlap" + prior: str = "shared" prior_count: int = 2 onset_count: int = 1 query: str = "later" @@ -76,7 +78,7 @@ def periods(self): if self.prior == "none": return () end = date(1999, 12, 31) - if self.prior == "overlap": + if self.prior == "shared": end = date(2000, 1, 31) return ((date(1999, 1, 1), end),) @@ -165,9 +167,7 @@ def favorable_statuses(case): ), None, ) - if first is None or any( - quarter(a) <= first <= quarter(b) for a, b in case.periods - ): + if first is None: continue lawful += 1 starts.add(first) @@ -292,7 +292,7 @@ def test_status_oracle_review_completion_has_favorable_fully_status(): @pytest.mark.parametrize("blind", (False, True)) -@pytest.mark.parametrize("prior", ("none", "clear", "overlap")) +@pytest.mark.parametrize("prior", ("none", "clear", "shared")) @pytest.mark.parametrize("query", ("after", "later", "claiming")) @pytest.mark.parametrize("prior_count", (2, 3)) def test_status_oracle_completion_lattice(blind, prior, query, prior_count): @@ -304,14 +304,14 @@ def test_status_oracle_completion_lattice(blind, prior, query, prior_count): @settings(max_examples=24, deadline=None, derandomize=True) @example( blind=False, - prior="overlap", + prior="shared", prior_count=2, onset_count=1, query="later", ) @given( blind=st.booleans(), - prior=st.sampled_from(("none", "clear", "overlap")), + prior=st.sampled_from(("none", "clear", "shared")), prior_count=st.integers(2, 3), onset_count=st.integers(1, 2), query=st.sampled_from(("after", "later", "claiming")), diff --git a/tests/test_track_b_insured_status_status_stress.py b/tests/test_track_b_insured_status_status_stress.py index 18ea48e2f..b25150351 100644 --- a/tests/test_track_b_insured_status_status_stress.py +++ b/tests/test_track_b_insured_status_status_stress.py @@ -7,9 +7,10 @@ Space: women born 1940-1979, aged 31-58 at onset, onset from 1992, where Rule I (20/40) or blindness applies. Endings, queries, annual totals with at most -four partial years, no prior, a clear prior or an overlapping prior, and -blindness in a quarter of cases all vary by seed. A second generator adds a -DIB entitlement month, which ends a CURRENTLY window before the onset. A third +four partial years, no prior, a prior ending before the onset quarter or +one ending in it, and blindness in a quarter of cases all vary by seed. A +second generator adds a DIB entitlement month, which ends a CURRENTLY window +before the onset. A third draws ages 22-30 at onset, where 404.130(c) applies. A fourth declares a special-insured prior before age 31 and an onset after it, where 404.130(d) applies, and a fifth adds an unflagged prior between them. A declared prior @@ -23,7 +24,11 @@ Every annual placement and both all-prior treatments are enumerated. A lawful filling has its own first insured start (404.321(a)), and that start supplies -the current period for FULLY, CURRENTLY and the date last insured. Each +the current period for FULLY, CURRENTLY and the date last insured. The start +falls on the onset day or a later quarter's first day, after every prior's +last day, so it may share the quarter a prior ended (RS 00301.140 example 7). +A current period begun before age 31 without 404.130(b) opens 404.130(d) +after it, as a flagged prior does (404.130(d)(1)). Each returned status must equal the favorable Boolean over lawful fillings (RS 00301.230), and a true status must hold on a filling whose first start is the reported start. Each exact count, assignment and date last insured must @@ -239,10 +244,27 @@ def lawful_fillings(case, reading=LAST_40, *, keep=None, dated=True): ), None, ) - if first is None or any( - quarter(a) <= first <= quarter(b) for a, b in prior - ): + if first is None: continue + # This start began on 404.130(c) alone where 404.130(b) failed + # under both treatments, so 404.130(d) follows it. + own_special = ( + not blind + and first + < quarter(date(birth.year + 31, birth.month, birth.day)) + and not any( + disability( + birth, + credits, + first, + treatment, + False, + reading=reading, + paragraph_c=False, + ) + for treatment in ((prior, ()) if prior else ((),)) + ) + ) year, q = divmod(first, 4) start = ( onset if first == quarter(onset) else date(year, 3 * q + 1, 1) @@ -278,7 +300,7 @@ def lawful_fillings(case, reading=LAST_40, *, keep=None, dated=True): at, periods, blind, - special, + special or own_special, reading, ), ), diff --git a/tests/tier_counts.json b/tests/tier_counts.json index a3d3384e5..93b792150 100644 --- a/tests/tier_counts.json +++ b/tests/tier_counts.json @@ -1,7 +1,7 @@ { "schema_version": 1, "counts": { - "unit": 25445, + "unit": 25525, "artifact": 4271, "integration_psid": 1471, "reproduction_legacy": 520, From c25a32c801acf8d692faecef706b9dfbbd2c2214 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Tue, 3 Nov 2026 05:56:36 -0500 Subject: [PATCH 40/46] Limit round 23's note check to the insured modules (#562 round 23) At 8522452c, test_the_note_cites_only_tests_that_exist searched every folder under tests/ and read each module it found, though blind roles run these modules. It now lists only the tests folder and opens only the design note and the insured status modules, and test_the_note_check_reads_only_the_note_and_insured_modules checks each Path listing and open before it runs. Six local mutations of the check fail that guard, with no restricted open. Two of round 23's property tests drew 25 random records, and 7b5b126a fails only 568 of the M1 differential's 11,700 and 90 of the exit-month test's 300, so a run could miss the bite. Each now runs an explicit example that 7b5b126a fails, and against 7b5b126a 42 of round 23's 67 cases fail on every run. All three property tests pass on every input of their strategies at this head. The tier files add the guard (25,526 unit), and the README total, which missed round 23's 80 tests, reads 32,125. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 33 +++++++++-- tests/README-tiers.md | 4 +- ...est_track_b_insured_status_fix_round_23.py | 57 +++++++++++++++++-- tests/tier_counts.json | 2 +- 4 files changed, 83 insertions(+), 13 deletions(-) diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index 496885e4d..757a6f4c7 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -3283,6 +3283,10 @@ both give the same date. Its records put every 1997 to 2002 QC in the 40 quarters ending 2003Q1, so 404.130(b) holds there on every placement or on none. A run over its whole strategy space, 11,700 records, computed 11,599 that agree and refused the other 101 by the long-period register entry's name. +`7b5b126a` gives a different date for 568 of those records, so 25 random draws +miss them all in about 29% of runs. The test now always runs one of them: the +review's record with four QCs in each of 1998 to 2000, where `7b5b126a` ended +the date at 2012-09-30 and the rule gives 2012-12-31. ### A period that shares the quarter a prior ended in @@ -3322,7 +3326,8 @@ failed at 3 of 6, where the law gives 6 of 6 years after it, which the history leaves out, and a quarterly QC or earnings a caller declares after the exit quarter stays an input error (`test_quarterly_bounds_name_themselves`). Every exit month of a year gives the -December exit's result (`test_the_exit_month_moves_nothing_in_its_year`), 40 +December exit's result (`test_the_exit_month_moves_nothing_in_its_year`, whose +example is a February exit with four 2020 QCs that `7b5b126a` cut to one), 40 QCs need no later quarter (`test_forty_qcs_need_no_later_quarter`), an UNKNOWN exit year refuses whatever its exit month (`test_an_unknown_exit_year_refuses_whatever_its_exit_month`), and an @@ -3479,7 +3484,12 @@ B.2.g and log Mary Brown's count (nit 27); and the note corrects the round 21 and 22 slips the review found (nit 28). `test_the_note_cites_only_tests_that_exist` checks that every test this note cites exists and that it cites no scratch file, and the PR body carries the -ledger path and current counts (low 20, nit 30). +ledger path and current counts (low 20, nit 30). Blind roles run these +modules, so the check lists only the tests folder and opens only this note and +the insured status modules; at `8522452c` it searched every folder under +`tests/` and read each module it found. +`test_the_note_check_reads_only_the_note_and_insured_modules` checks each Path +listing and open before it runs. ### Renamed, retired and superseded @@ -3576,11 +3586,21 @@ blindness begin a prior before 1973, and `nit29` restores the general detail. each low's check. `first_onset_short` and `first_onset_odd` move 404.130(c)'s 12-quarter floor or round its half up. Each of the 29 fails round 23's module. -Against `7b5b126a`, 42 of round 23's 66 cases fail. The 24 that pass hold +Six local mutations of the note check each fail its read guard before the check +opens a file outside this note and the insured status modules: a recursive +`rglob`, a `**` glob, a subfolder glob, and a flat glob, a byte read and an +`iterdir` over every module in `tests/`. The list holds mutations of the rule's +source only, so it leaves these six out. + +Against `7b5b126a`, 42 of round 23's 67 cases fail. The 25 that pass hold behavior `7b5b126a` already had: the example 7 quote, the seven middle completions and the two contradicted flags, the January 1973 prior, the pre-1956 prior that computes, the seven published first onsets, the two valid -entitlement months, two quarterly bounds and the note's citations. +entitlement months, two quarterly bounds, the note's citations and its read +guard. The 42 fail on every run: `7b5b126a` raises an input error on all 61 +onsets of `test_any_onset_after_the_prior_day_keeps_its_own_start`, and the +other two property tests each run an example `7b5b126a` fails. All three pass +on every input of their strategies at this head, 11,700, 61 and 300 of them. These tests execute the invariants this round adds: @@ -3621,7 +3641,10 @@ These tests execute the invariants this round adds: or UNKNOWN-earnings refusal, and the row keeps its weight (`test_an_unsupported_prior_refuses_before_unknown_earnings`, `test_past_blindness_begins_a_prior_only_from_1973`, - `test_a_1965_prior_cannot_rest_on_past_blindness`). + `test_a_1965_prior_cannot_rest_on_past_blindness`); +- the note check lists only the tests folder and opens only this note and the + insured status modules + (`test_the_note_check_reads_only_the_note_and_insured_modules`). ## Not in scope diff --git a/tests/README-tiers.md b/tests/README-tiers.md index a3d8abbcf..c982476b6 100644 --- a/tests/README-tiers.md +++ b/tests/README-tiers.md @@ -39,9 +39,9 @@ pytest --collect-only -q -m oracle_policyengine | tail -1 | Tier | Tests at HEAD | |---|---:| -| `unit` | 25,525 | +| `unit` | 25,526 | | `artifact` | 4,271 | | `integration_psid` | 1,471 | | `reproduction_legacy` | 520 | | `oracle_policyengine` | 337 | -| **Total** | **32,044** | +| **Total** | **32,125** | diff --git a/tests/test_track_b_insured_status_fix_round_23.py b/tests/test_track_b_insured_status_fix_round_23.py index fc6655175..2ad52066c 100644 --- a/tests/test_track_b_insured_status_fix_round_23.py +++ b/tests/test_track_b_insured_status_fix_round_23.py @@ -30,7 +30,7 @@ from pathlib import Path import pytest -from hypothesis import given, settings +from hypothesis import example, given, settings from hypothesis import strategies as st from populace_dynamics.track_b import insured_status as i @@ -242,6 +242,7 @@ def test_a_placement_or_year_that_decides_the_basis_refuses(): @PROPERTY +@example(qcs_1997=0, qcs_2001=2, qcs_2002=4, qcs_2012=1, end=M1_END) @given( qcs_1997=st.integers(0, 4), qcs_2001=st.integers(1, 4), @@ -255,7 +256,9 @@ def test_an_ended_current_period_counts_as_the_prior_it_becomes( # Differential: the 1997 to 2002 QCs all sit in the 40 quarters ending # 2003Q1, so 404.130(b) holds there on every placement or on none, and # the period's flag follows. The same period listed as a prior with that - # flag has the same DLI. + # flag has the same DLI. The example adds four QCs in each of 1998 to + # 2000 to the review's record, which leaves 18 of 40 at 2003Q1; without + # the flag, 7b5b126a ended its DLI at 2012-09-30 rather than 2012-12-31. annual = { 1997: qcs_1997, 1998: 4, @@ -459,6 +462,7 @@ def years(person): @PROPERTY +@example(qcs_2019=0, qcs_2020=4, exit_month=2) @given( qcs_2019=st.integers(0, 4), qcs_2020=st.integers(0, 4), @@ -468,7 +472,8 @@ def test_the_exit_month_moves_nothing_in_its_year( qcs_2019, qcs_2020, exit_month ): # An exit bars later years only, so every exit month of 2020 gives the - # December exit's result. + # December exit's result. In the example, 7b5b126a cut a February exit's + # four 2020 QCs to one. person = _person(date(2000, 6, 15)) month = date(2024, 1, 1) @@ -1286,14 +1291,56 @@ def test_quarterly_bounds_name_themselves(year, declared, message): def test_the_note_cites_only_tests_that_exist(): # The note names tests as its evidence, so each must still run, and it - # cites no uncommitted scratch file. + # cites no uncommitted scratch file. That evidence lives in the insured + # status modules, so the check opens those and no other test file. tests = Path(__file__).resolve().parent note = (tests.parent / "docs/design/track_b_insured_status.md").read_text() defined = set() - for module in tests.rglob("*.py"): + for module in tests.glob("test_track_b_insured_status*.py"): defined.add(module.stem) defined.update( re.findall(r"^\s*def (test_\w+)", module.read_text(), re.M) ) assert sorted(set(re.findall(r"`(test_\w+)", note)) - defined) == [] assert "scratch/" not in note + + +def test_the_note_check_reads_only_the_note_and_insured_modules( + monkeypatch, +): + # Blind roles run these modules, so the note check may list only the + # tests folder itself and open only the note and the insured status + # modules. The guard checks each Path listing and open before it runs. + tests = Path(__file__).resolve().parent + note = tests.parent / "docs/design/track_b_insured_status.md" + path_open, glob, iterdir = Path.open, Path.glob, Path.iterdir + opened = [] + + def checked_open(path, *args, **kwargs): + resolved = path.resolve() + assert resolved == note or ( + resolved.parent == tests + and resolved.name.startswith("test_track_b_insured_status") + ), resolved + opened.append(resolved) + return path_open(path, *args, **kwargs) + + def flat_glob(path, pattern, *args, **kwargs): + assert path.resolve() == tests, path + assert "**" not in pattern and "/" not in pattern, pattern + return glob(path, pattern, *args, **kwargs) + + def flat_iterdir(path): + assert path.resolve() == tests, path + return iterdir(path) + + def recursive(path, *args, **kwargs): + raise AssertionError(f"recursive search of {path}") + + monkeypatch.setattr(Path, "open", checked_open) + monkeypatch.setattr(Path, "glob", flat_glob) + monkeypatch.setattr(Path, "iterdir", flat_iterdir) + monkeypatch.setattr(Path, "rglob", recursive) + monkeypatch.setattr(Path, "walk", recursive) + test_the_note_cites_only_tests_that_exist() + assert note in opened and Path(__file__).resolve() in opened diff --git a/tests/tier_counts.json b/tests/tier_counts.json index 93b792150..6baed6607 100644 --- a/tests/tier_counts.json +++ b/tests/tier_counts.json @@ -1,7 +1,7 @@ { "schema_version": 1, "counts": { - "unit": 25525, + "unit": 25526, "artifact": 4271, "integration_psid": 1471, "reproduction_legacy": 520, From aeef5c749683318491d75c2670641611cdafd4e9 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Tue, 3 Nov 2026 06:04:17 -0500 Subject: [PATCH 41/46] Align #562's issue draft with round 23's contracts (#562 round 23) The rulespec-us issue draft said malformed input must fail before any coverage refusal, which round 23's precedence contradicts: a listed prior that no completion supports now refuses by name before the rule calls a later period impossible. The draft now states the contract the rule keeps: a declaration that contradicts itself fails before the rule runs, and otherwise an input error means every filling is invalid. Its long-period bullet named two readings, and round 23 lists a third parse for Max under d1920. It now names all three and says what the Python rule does with each. The design note's scope line also gets back the spaces in "pinned 413, 414 and 423(c)(1) rules". Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 3 ++- .../track_b_insured_status_rulespec_issue.md | 21 ++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index 757a6f4c7..7ffbe8695 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -3654,4 +3654,5 @@ finding, original SSN evidence, or totalization agreement is implemented. This module supplies B6a's statutory insured-status predicate; it does not establish the empirical risk denominator or admit B6a forecasting. OP8(d)'s pre-entry convention remains Max's decision. No Axiom differential is -claimed: the companion issue draft requests pinned413/414/423(c)(1) rules. +claimed: the companion issue draft requests pinned 413, 414 and 423(c)(1) +rules. diff --git a/docs/design/track_b_insured_status_rulespec_issue.md b/docs/design/track_b_insured_status_rulespec_issue.md index 12e194988..ab6a15c96 100644 --- a/docs/design/track_b_insured_status_rulespec_issue.md +++ b/docs/design/track_b_insured_status_rulespec_issue.md @@ -50,9 +50,13 @@ Required outputs are annual QC ranges, favorable assigned-quarter witnesses, fully/currently/disability insurance, required counts and decision windows, DLI or a DLI range, unknown years, convention identifiers and the `decided_despite_unknowns` flag. Each unsupported configuration must return a -named refusal retained in the shared evaluator denominator. Malformed input -must fail before any coverage refusal. Output and refusal records must bind -the rule revision and input declaration. +named refusal retained in the shared evaluator denominator. A declaration that +contradicts itself, such as a period that ends before it starts, fails before +the rule runs. Otherwise an input error means every filling of the declaration +is invalid; where the encoding can't show that, it refuses by name and keeps +the row, so a listed prior that no completion supports refuses before the rule +calls a later period impossible. Output and refusal records must bind the rule +revision and input declaration. ## Pasteable review_finding @@ -123,10 +127,13 @@ case inventory, preserving its coverage labels. In particular: handling and creditable endpoint quarters. Preserve any source-versus-rule discrepancy documented by the Python lane; do not make the compiler imitate an erratum to force parity. -- Past 40 counted quarters a subsequent-special period has two readings: - half the whole period under 42 USC 423(c)(1)(B)(iii), and 20 of the last - 40 quarters under 20 CFR 404.130(d)(2). Execute both, and refuse where - they differ. The Python rule logs this as +- Past 40 counted quarters a subsequent-special period has three readings: + half the whole period after 21 under 42 USC 423(c)(1)(B)(iii), 20 of the + last 40 quarters under 20 CFR 404.130(d)(2) and RS 00301.147, and half the + whole period capped at 20 QCs, counted anywhere in it. Execute each, and + refuse by name where they differ. The Python rule computes on + 404.130(d)(2), refuses by name where the uncapped half would insure, and + leaves the third parse to Max; it logs all three as `us:oasdi-insured-subsequent-special-long-period`, and d1920 holds the pattern. - Explicitly refuse unsupported deemed, alien, military/railroad, Medicare, From fc689ecbd4474e505e9b62070039b6de4820b6e7 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Tue, 3 Nov 2026 10:59:46 -0500 Subject: [PATCH 42/46] Raise on a prior that ends past FRA and pin three branches (#562 round 23) A pre-screen of 8522452c found three lows and two nits, and tried twelve mutations of its own. Person.__post_init__ still capped a listed prior's end at the month before FRA, while round 23 made the same end on the current period an input error. 404.321(c)(1), and 404.321(b) for a disability that ended before December 1980, end every period by then, so a later declared end has no lawful filling. Both now raise InvalidFamilyInput. Round 3's tests and the historical boundary lattice declared such ends, so they now check that the latest lawful end constructs and a later one raises, and the lattice ends the 1890 cohort's prior by January 1955. Three round 23 branches had no test that failed when they broke. A death later in the query month now keeps the living count under 404.110(b)(2)(iv) (test_a_death_after_the_query_keeps_the_living_count). A period that begins in the quarter its holder attains 31 rests on 404.130(d), not 404.130(c) (test_a_period_begun_in_the_age_31_quarter_rests_on_paragraph_d). An open flag never flags the current period, so where every placement meets 404.130(b) in its first quarter, 404.130(d) doesn't reach the quarters after it (test_an_open_flag_keeps_paragraph_b_where_every_placement_meets_it). Each fails when a mutation breaks its branch. The current-period comment and the low 12 test cited 404.321(b) for the FRA end; they now cite 404.321(c)(1). The RS 00301.340 note in the examples gets back its dollar amounts, and the Joseph note no longer breaks mid-sentence. The unit tier rises by the three new tests (26,323 unit, 33,178 in all). The design note records the changes, eight new mutations (107 in all) and the counts against 7b5b126a (44 of round 23's 70 cases fail). It also accounts for the pre-screen's twelve mutations. Ten fail named tests. Two survive every insured status module. One changes no answer across 1,500 generated blind records. Every change the other makes across 11,000 generated records turns a refusal into a result, and the stress oracle accepts each result it can judge on both cap readings. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 187 ++++++++++++++---- .../track_b/insured_status.py | 19 +- tests/README-tiers.md | 4 +- .../data/track_b/insured_status_examples.yaml | 21 +- ..._b_insured_status_classification_oracle.py | 12 +- ...est_track_b_insured_status_fix_round_23.py | 102 +++++++++- ...ck_b_insured_status_fix_round_3_periods.py | 42 ++-- tests/tier_counts.json | 2 +- 8 files changed, 309 insertions(+), 80 deletions(-) diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index 7ffbe8695..9255558b0 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -388,8 +388,8 @@ inventing a future end. Continuity within the query quarter can leave its endpoint ambiguous; continuity into a later quarter proves that the query quarter is interior. -Established starts at or after FRA are invalid even if prior history is UNKNOWN, and every supplied prior period is capped at -the month before FRA. The standalone requirement helper shares these +Established starts at or after FRA are invalid even if prior history is UNKNOWN, and every supplied prior period must end by +the month before FRA, so a later declared end is an input error (round 23). The standalone requirement helper shares these limits. A start in the FRA attainment month is also invalid because its mandatory end would precede its start, including a first-day birthday whose FRA is attained at the end of the previous month. The FRA date and @@ -843,7 +843,7 @@ to a statutory sentence that does not state it. | --- | --- | | I1. A period cannot end before its onset or derived insured start; a supplied administrative end requires a declared established current period and closes a calendar month. | A216(i)(2)(C) says a period begins on the disability day or "the first day of the first quarter thereafter"; (D) says it ends "with the close" of the earlier listed month. C321(a), (c) agree. Every specialist route must still have a nonempty chronological period; no ordinary witness alone decides whether a specialist supplied the insured start. The end/established association is also a declaration contract. | | I2. Birth, disability onset, death, prior periods, entitlement, and SSN assignment must have consistent lifetime ordering. A query or coverage end cannot precede birth; medical onset or supplied entitlement cannot follow the query month; onset cannot follow death. A DIB entitlement month must precede the FRA month, and an RIB entitlement month cannot precede the month of attaining 62 (round 23). | B404.102 defines "You or your" as "the worker whose insured status is being considered"; A216(i)(2)(A) requires a period "during which an individual was under a disability". Dates refer to that same living worker. This lifetime and observation-calendar contract is independent of the insured route. It permits onset later within the query month and the quarter of death rather than imposing a day-of-query restriction. The entitlement bounds are an interface premise: the benefit calendar comes from Act 223(a)(1) and 202(a)(2), which are not captured, and an event outside it contradicts the declaration rather than posing an insured-status question. | -| I3. An established period must start before its FRA-ending boundary, including no start in the FRA month. A declared current-period end after the preceding month end is an input error, as a continuity date after it already was (round 23); supplied prior periods are capped at that month end. | A216(i)(2)(B): "no such period shall begin ... after such individual attains retirement age"; (D)(i) ends at "the month preceding the month" of FRA. C321(a), (c)(1) say the same. A start after the mandatory month-end is impossible under both clauses, including first-day birthdays. The cap supplies no evidence against an earlier UNKNOWN end. No completion ends the current period later, so a later declared end is a contradiction, not a value to cap. | +| I3. An established period must start before its FRA-ending boundary, including no start in the FRA month. A declared end of the current period or a supplied prior after the preceding month end is an input error, as a continuity date after it already was (round 23). | A216(i)(2)(B): "no such period shall begin ... after such individual attains retirement age"; (D)(i) ends at "the month preceding the month" of FRA. C321(a), (c)(1) say the same. A start after the mandatory month-end is impossible under both clauses, including first-day birthdays. The cap supplies no evidence against an earlier UNKNOWN end. No completion ends a period later, so a later declared end is a contradiction, not a value to cap. | | I4. Supplied prior periods precede the current onset and query, share no day with each other, and stay within the lifetime. A period may begin in the quarter the one before ended (round 23). | B404.130(f) refers to "a prior period of disability established for you". C321(a) says "Your period of disability begins on the day your disability begins if you are insured for disability on that day", and C321(b)–(c) end a period on a month's last day, so a new period can begin in the quarter the last one ended; RS .140 example 7 is that case. The shared quarter is an endpoint quarter of both periods, which B404.146(d)(1) and B404.130(f) count where it is a QC. Days, not quarters, are the declared history representation; specialist credits cannot change what "prior" means. UNKNOWN history is not treated as supplied empty history. | | I5. A supplied `special_insured` prior period begins before the age-31 attainment quarter. | B404.130(d)(1): a prior period "began before age 31" and the worker "were only insured under paragraph (c)"; (c)(1) requires age 31 not yet attained. A216(i)(3)(B)(iii) expressly uses "before the quarter" of age 31. The flag declares this particular adjudicated young-worker route, not every possible special credit regime. | | I6. An alien worker's actual pre2004 SSN assignment conflicts with declared SSPA applicability; birth on/after January 1, 2004 conflicts with declared exemption. Both never-assigned and an assigned SSN, or assignment before birth, remain invalid. A worker born before 2004 may pair a post2003 assignment or never-assigned status with an adjudicated exemption. | RS .102 B.1 says an alien assigned an SSN before 2004 "is exempt", including a nonwork SSN. B.3.b says, "If an alien worker could have legitimately been assigned an SSN before 1/1/2004, the worker is exempt from the requirements of section 211 of the SSPA." Its wrong-number SS-5 scenario issued another person's number "instead of assigning the alien worker their own SSN". Thus observed or convention-filled exemption overrides either later-assignment or never-assigned presumptions when legitimate pre2004 assignment was possible. Birth on/after January 1, 2004 rules out that exception independently of the assignment record. B.4.b's worker without an SSN "is nevertheless considered to meet the work SSN requirement" when work-authorized; meeting that requirement alone supplies no exemption. | @@ -3228,8 +3228,11 @@ These tests execute the invariants this round adds: Verification class: statutory conformance on invented declarations only. This correction admits no population, behavioral, payment, or forecast claim. An independent review of `7b5b126a` reported seven mediums, 17 lows and six nits -(PR #562 comment 6596920658). The rows and passages above now state the rule as -it stands, and this section records what changed and why. +(PR #562 comment 6596920658). A pre-screen of `8522452c` then found that a +listed prior's end past the statutory end still capped silently, that two of +this round's branches had no test that failed when they broke, and two text +slips. The rows and passages above now state the rule as it stands, and this +section records what changed and why. ### A current period begun on 404.130(c) alone @@ -3262,14 +3265,41 @@ in that quarter, the function returns None, and with listed priors it stays open whenever some placement meets 404.130(b). `_settle_current_basis` then computes the date on both bases and refuses by name where they differ, with ASSIGNMENT_COMPLEXITY where placement decides and UNKNOWN_EARNINGS where an -UNKNOWN year does. With one 1997 QC and four in each of 1998 to 2000 added, -404.130(b) finds 19 of 40 at 2003Q1. A 1993 QC counts there only in 1993Q2 to -Q4, and no later window counts it, so its placement decides between the two -dates, as an UNKNOWN 1997 does +UNKNOWN year does. It reads the flag at the lower completions' start, which is +also the upper completions' start, since the rule refuses by UNKNOWN_EARNINGS +wherever the two differ. With one 1997 QC and four in each of 1998 to 2000 +added, 404.130(b) finds 19 of 40 at 2003Q1. A 1993 QC counts there only in +1993Q2 to Q4, and no later window counts it, so its placement decides between +the two dates, as an UNKNOWN 1997 does (`test_a_placement_or_year_that_decides_the_basis_refuses`). The flag adds 404.130(d) only for quarters after the period, so only the date last insured can move, and FULLY computes on either basis. +An open flag never flags the period itself: `_with_current_period` appends it +unflagged, and `_settle_current_basis` checks that the date stands on both +bases. Listed priors leave the flag open even where every placement meets +404.130(b). A woman born 1976-12-08 has a listed prior from 2002-03-19 to +2006-01-31 and an onset on 2007-07-05, in 2007Q3, the quarter before she +attains 31. Counting the prior's quarters, as 404.130(f) allows where that +helps, the 40 quarters from 1997Q4 hold 24 QCs, or 25 when her one 2007 QC +comes before Q4, and leaving them out still leaves at least 22. So 404.130(b) +began the period on every placement, and 20 of 40 last holds at 2012Q2 +(`test_an_open_flag_keeps_paragraph_b_where_every_placement_meets_it`). A +mutation that flags the period whenever the flag stays open brings in +404.130(d) more than 40 quarters after she attained 21, and the record then +refuses by the long-period register entry's name. + +404.130(c)(1) asks that its holder "have not become (or would not become) age +31" in the quarter, so a period that begins in the quarter its holder attains +31 never rests on 404.130(c), and `_current_period_special` leaves it +unflagged. A woman born 1975-02-15 attains 31 on 2006-02-14, in 2006Q1, the +quarter of her January 20 onset. With a flagged prior from 1997Q2 through +1999, she is disabled again at 31 (404.130(d)(1)), so 404.130(d) counts the 40 +quarters from 1996Q2 less the ten inside the prior after its first. Her 17 QCs +meet half of 30, and the period begins on the onset day on the +subsequent-special rule +(`test_a_period_begun_in_the_age_31_quarter_rests_on_paragraph_d`). + One more QC can bring the date earlier, as the law reads. With 19 QCs before the onset, 404.130(b) fails at 2003Q1, the period rests on 404.130(c) alone, and 404.130(d) holds through 2012Q4. A second 1997 QC makes 20 of 40 at 2003Q1, @@ -3384,6 +3414,14 @@ reads 404.115's table from the captured regulation and checks column II for a living man and woman of every cohort at 62, 63, 64 and 66, and the death columns of the 33 rows from 1893 through 1925. +The rule reads him as living unless he died by the day it reads his status, the +query month's first day. If he dies later in December 1971, he is living on +December 1, so the count runs through 1972 and he needs 22. If he dies on +December 1, 404.110(b)(3) counts the years before 1971, the year he died, and +his 20 QCs make him fully insured +(`test_a_death_after_the_query_keeps_the_living_count`). No captured source +reads the count for the whole month of a death. + ### A flagged prior needs one placement for both halves A flag records a prior "for which you were only insured under paragraph (c)", @@ -3446,14 +3484,25 @@ prior the flag can carry shows nothing missing (`_flag_carries_prior`, These lows and nits change code, each with a test: -- low 12: a declared period end after the statutory FRA end raises - `InvalidFamilyInput`, as a continuity date after it already did, where - `7b5b126a` capped it silently - (`test_declared_dates_past_the_statutory_end_are_input_errors`); +- low 12: a declared end of the current period or a listed prior after the + statutory FRA end raises `InvalidFamilyInput`, as a continuity date after it + already did, where `7b5b126a` capped both silently + (`test_declared_dates_past_the_statutory_end_are_input_errors`). Round 3 + capped a listed prior's end, so its tests now check that the latest lawful + end constructs and a later one raises + (`test_prior_period_ends_by_fra_for_status_and_requirement_helper`, + `test_every_supplied_prior_period_has_the_statutory_fra_cap`), and + `test_classification_oracle_historical_boundary_lattice` ends the 1890 + cohort's prior by January 1955, the month before it attains 65 + (404.321(b)); - low 16: a DIB entitlement month at or after FRA, and an RIB month before the one in which the holder attains 62, raise `InvalidFamilyInput` (Act 223(a)(1), 202(a)(2)), where `7b5b126a` let them decide CURRENTLY - (`test_entitlement_months_must_be_possible`); + (`test_entitlement_months_must_be_possible`). Whether an RIB can begin in + the month a holder born on the first attains 62, or must wait for a month + throughout which the holder is 62, rests on Act 202(a)'s text, which no + captured source holds, so the check stays at the attainment month until a + follow-up captures it; - low 19: the pre-May-1983 refusal for a flagged prior fires only where the holder's age-31 quarter begins before May 1983, since 404.130(c) decided an onset before 31 under the earlier law too @@ -3481,13 +3530,17 @@ entries read as placement-dependent intermediate counts (low 18); the long-period register entry adds the third parse (low 22); the fiscal-year helper names the 1971 to 1972 gap (nit 26); the examples cite RS 00301.345 B.2.g and log Mary Brown's count (nit 27); and the note corrects the round 21 -and 22 slips the review found (nit 28). +and 22 slips the review found (nit 28). The pre-screen's two slips change text +too. The current-period comment and the low 12 test now cite 404.321(c)(1) for +the FRA end, where they cited 404.321(b), which governs a disability that ended +before December 1980. The RS 00301.340 note in the examples restores the dollar +amounts it had lost, and the Joseph note no longer breaks mid-sentence. `test_the_note_cites_only_tests_that_exist` checks that every test this note cites exists and that it cites no scratch file, and the PR body carries the -ledger path and current counts (low 20, nit 30). Blind roles run these -modules, so the check lists only the tests folder and opens only this note and -the insured status modules; at `8522452c` it searched every folder under -`tests/` and read each module it found. +ledger path and current counts (low 20, nit 30). Blind roles run these modules, +so the check lists only the tests folder and opens only this note and the +insured status modules; at `8522452c` it searched every folder under `tests/` +and read each module it found. `test_the_note_check_reads_only_the_note_and_insured_modules` checks each Path listing and open before it runs. @@ -3508,6 +3561,7 @@ reading this round corrects: | round 13 | test_disability_witness_uses_the_legal_annual_start_filling | `test_disability_witness_counts_the_quarter_a_prior_ended` | | round 13 | test_post1955_clear_start_cannot_replace_overlapped_alternate | `test_every_test_refuses_a_shared_quarter_alternate_by_name` | | round 13 | test_review_alternate_start_must_clear_same_prior_overlap | `test_an_alternate_start_can_share_the_quarter_a_prior_ended` | +| round 3 periods | test_prior_period_is_capped_at_fra_for_status_and_requirement_helper | `test_prior_period_ends_by_fra_for_status_and_requirement_helper` | | round 4 routes | test_possible_lower_earnings_filling_prevents_upper_overlap_input_error | `test_every_onset_year_filling_starts_a_valid_period` | | round 4 routes | test_unknown_earnings_can_avoid_derived_prior_quarter_overlap | `test_unknown_onset_year_earnings_decide_the_current_start` | | round 6 ordering | test_deferred_quarter_fillings_keep_fixed_minimum_and_valid_middle | `test_deferred_quarter_fillings_survive_a_shared_onset_quarter` | @@ -3555,8 +3609,8 @@ and retires I13 and B15. ### Mutations The list of mutations (`round_23_mutations` in -`track_b_insured_status_mutations.json`) takes round 22's 70 and adds 29 of -this round's own, for 99. Round 22's anchors still hold for 53 of the 70. The +`track_b_insured_status_mutations.json`) takes round 22's 70 and adds 37 of +this round's own, for 107. Round 22's anchors still hold for 53 of the 70. The other 17 touched code round 23 rewrote, and each keeps its intent at the code that now does that job: two at the binding check, which now also asks for a basis; five in `_keeps_priors` and nine in `_prior_basis`, which now pass @@ -3570,21 +3624,30 @@ rule only where more than 4,096 completions stand open: it refuses on their number instead of the flag, and `test_a_flag_every_completion_contradicts_refuses_by_that_name` kills it. -Round 23's own 29 undo one change each. `m1_flag`, `m1_open_basis` and +Round 23's own 37 undo one change each. `m1_flag`, `m1_open_basis` and `m1_settle` drop the current period's flag, close an open basis, or skip the -basis check. `m2_listed` and `m2_current` bar a shared quarter again. `m3_exit` -and `m13_birth` restore the exit-quarter and birth-quarter bars. `m4_rank` -drops the earlier-quarter rank, `m5_earliest` the onset-quarter bound under -UNKNOWN priors, and `basis_split_unreported` and `basis_split_always` misreport -the basis split. `m6_men` ends a living man's count at the query. `m7_flagfits` -drops the one-placement check, and `flag_middle` searches only the bounds. +basis check, and `m8_age31` lets a period that begins in the age-31 quarter +rest on 404.130(c). `open_flag_as_special` flags the period whenever its flag +stays open, and `settle_accepts_open_flag` returns from the basis check on an +open flag without comparing the two dates. `m2_listed` and `m2_current` bar a shared quarter again. +`m3_exit` and `m13_birth` restore the exit-quarter and birth-quarter bars. +`m4_rank` drops the earlier-quarter rank, `m5_earliest` the onset-quarter bound +under UNKNOWN priors, and `no_earliest_widening` the step in +`_status_decision` that widens an insured status's upper qualifying quarter to +that bound. `basis_split_unreported` and `basis_split_always` misreport the +basis split. `m6_men` ends a living man's count at the query, and +`m4_living` reads a man who died by the query as living. `m7_flagfits` drops +the one-placement check, `flag_fits_always` makes that check pass wherever +404.130(b) can hold, and `flag_middle` searches only the bounds. `precedence_possible` and `precedence_unknown` let the input error or the UNKNOWN-earnings refusal come first. `pre1956_scan` scans past the quarters the prior covers, and `pre1956_none` refuses the B.1 prior. `low21` lets past -blindness begin a prior before 1973, and `nit29` restores the general detail. -`low12`, `low16_dib`, `low16_rib`, `low19`, `low23`, `low24` and `nit25` undo -each low's check. `first_onset_short` and `first_onset_odd` move 404.130(c)'s -12-quarter floor or round its half up. Each of the 29 fails round 23's module. +blindness begin a prior before 1973, `blind_basis_1972` lets it begin one in +1972, and `nit29` restores the general detail. +`low12`, `low12_prior`, `low16_dib`, `low16_rib`, `low19`, `low23`, `low24` and +`nit25` undo each low's check. `first_onset_short` and `first_onset_odd` move +404.130(c)'s 12-quarter floor or round its half up. Each of the 37 fails round +23's module. Six local mutations of the note check each fail its read guard before the check opens a file outside this note and the insured status modules: a recursive @@ -3592,15 +3655,47 @@ opens a file outside this note and the insured status modules: a recursive `iterdir` over every module in `tests/`. The list holds mutations of the rule's source only, so it leaves these six out. -Against `7b5b126a`, 42 of round 23's 67 cases fail. The 25 that pass hold +The pre-screen of `8522452c` tried twelve mutations of its own. Seven now +stand on the list: `m4_living` and `m8_age31`, which break the two branches it +found untested, and `open_flag_as_special`, `settle_accepts_open_flag`, +`blind_basis_1972`, `no_earliest_widening` and `flag_fits_always`. Two repeat +`m2_listed` and `m4_rank`. One moves the QC module's period-start bound, and +`test_disability_exclusion_never_adds_qc` and +`test_death_future_and_disability_endpoint_exclusions` fail on it. Two survive +every insured status module, the stress module included, and the round adds no +test for either: + +- `special_ignores_blindness` lets a blind holder's current period carry the + flag. 404.130(e) asks a blind holder only for fully insured status, so the + DISABILITY witness takes that route alone (`blindness_fully_only`). Across + 1,500 generated blind records, 1,459 with a listed prior and 714 computing, + it changes no answer. +- `first_start_flag_true_only` reads an open flag as closed in the first-start + search. Across 6,000 generated records it turns 32 refusals into results and + changes no result, and across 5,000 records without priors it changes + nothing. All 32 have listed priors, and with listed priors + `_current_period_special` leaves the flag open wherever some placement meets + 404.130(b). The stress oracle judges ten of them, the records without an + exit month whose placements it can enumerate (at most 2,304 each), and for + each its lawful fillings give the mutation's result on both readings of the + long-period cap. It can't judge the other 22: 19 end with an exit month, which it doesn't + model, and three hold 331,776, 14,155,776 and 764,411,904 placements. Each + difference found turns a refusal into a result, and the stress oracle finds + every refusal it judges needless, so the round pins none in a test. Closing + the listed-prior flag where every placement meets 404.130(b) waits for a + later round. + +Against `7b5b126a`, 44 of round 23's 70 cases fail. The 26 that pass hold behavior `7b5b126a` already had: the example 7 quote, the seven middle completions and the two contradicted flags, the January 1973 prior, the pre-1956 prior that computes, the seven published first onsets, the two valid -entitlement months, two quarterly bounds, the note's citations and its read -guard. The 42 fail on every run: `7b5b126a` raises an input error on all 61 -onsets of `test_any_onset_after_the_prior_day_keeps_its_own_start`, and the -other two property tests each run an example `7b5b126a` fails. All three pass -on every input of their strategies at this head, 11,700, 61 and 300 of them. +entitlement months, two quarterly bounds, the onset in the age-31 quarter, the +note's citations and its read guard. The 44 fail on every run: `7b5b126a` +raises an input error on all 61 onsets of +`test_any_onset_after_the_prior_day_keeps_its_own_start`, the other two +property tests each run an example `7b5b126a` fails, and `7b5b126a` ends the +open-flag record's date at 2011-09-30. All three pass on every +input of their strategies at this head, 11,700, 61 and 300 of them. These tests execute the invariants this round adds: @@ -3610,9 +3705,15 @@ These tests execute the invariants this round adds: (`test_an_ended_current_period_counts_as_the_prior_it_becomes`, `test_a_period_begun_on_paragraph_c_alone_opens_paragraph_d_after_it`, and the stress oracle through `check`); +- a period that begins in the quarter its holder attains 31 never rests on + 404.130(c) + (`test_a_period_begun_in_the_age_31_quarter_rests_on_paragraph_d`); - where placement or an UNKNOWN year decides that basis and the bases give different dates, the date refuses by name and keeps its row (`test_a_placement_or_year_that_decides_the_basis_refuses`); +- an open flag never flags the current period, so where every placement meets + 404.130(b) in its first quarter, 404.130(d) doesn't reach the quarters after + it (`test_an_open_flag_keeps_paragraph_b_where_every_placement_meets_it`); - periods share no day, and a period may begin in the quarter a prior ended (`test_rs00301_140_example_7_begins_on_the_onset_day`, `test_any_onset_after_the_prior_day_keeps_its_own_start`, @@ -3629,9 +3730,15 @@ These tests execute the invariants this round adds: `test_a_prior_basis_split_widens_the_qualifying_quarters`, `test_unknown_priors_reach_the_onset_quarter`); - a living man born before January 2, 1913 counts elapsed years to 65 or 1975 - from the year he reaches 62, and each 404.115 cohort gets its column + from the year he reaches 62, he stays living until the day he dies, and each + 404.115 cohort gets its column (`test_the_404_115_table_gives_each_cohort_its_count`, - `test_a_man_who_reached_62_before_1973_counts_to_65`); + `test_a_man_who_reached_62_before_1973_counts_to_65`, + `test_a_death_after_the_query_keeps_the_living_count`); +- no period, current or listed prior, ends after the statutory FRA end, and a + declared end past it is an input error + (`test_declared_dates_past_the_statutory_end_are_input_errors`, + `test_every_supplied_prior_period_has_the_statutory_fra_cap`); - a flagged prior stands only on a placement where a special route passes and 404.130(b) fails (`test_a_flagged_prior_needs_paragraph_c_without_paragraph_b`, diff --git a/src/populace_dynamics/track_b/insured_status.py b/src/populace_dynamics/track_b/insured_status.py index 6e251c656..93f83c63a 100644 --- a/src/populace_dynamics/track_b/insured_status.py +++ b/src/populace_dynamics/track_b/insured_status.py @@ -493,8 +493,10 @@ def __post_init__(self): self.current_disability_period_end is not None and self.current_disability_period_end > fra_end ): - # 404.321(b) ends a period by the month before FRA, so no - # completion has a later end. + # 404.321(c)(1) ends a period by the month before FRA, and + # 404.321(b), for a disability that ended before December 1980, + # by the month before 65, which is FRA for anyone 65 by then. So + # no completion has a later end. raise InvalidFamilyInput( "Current period ends after its statutory FRA end" ) @@ -525,18 +527,17 @@ def __post_init__(self): and through > self.current_disability_period_end ) or (self.death_date is not None and through > self.death_date): raise InvalidFamilyInput("Period continuity follows its end") - periods = sorted( - ( - replace(p, end=min(p.end, fra_end)) if p.start < fra else p - for p in self.prior_disability_periods - ), - key=lambda p: p.start, - ) + periods = sorted(self.prior_disability_periods, key=lambda p: p.start) for i, period in enumerate(periods): if period.start >= fra or period.start > fra_end: raise InvalidFamilyInput( "Disability period begins at or after FRA" ) + if period.end > fra_end: + # The same 404.321 end binds a listed prior. + raise InvalidFamilyInput( + "Prior period ends after its statutory FRA end" + ) if period.start < self.birth_date or ( self.death_date is not None and period.end > self.death_date ): diff --git a/tests/README-tiers.md b/tests/README-tiers.md index 4575a9a99..b08f87794 100644 --- a/tests/README-tiers.md +++ b/tests/README-tiers.md @@ -39,9 +39,9 @@ pytest --collect-only -q -m oracle_policyengine | tail -1 | Tier | Tests at HEAD | |---|---:| -| `unit` | 26,320 | +| `unit` | 26,323 | | `artifact` | 4,527 | | `integration_psid` | 1,471 | | `reproduction_legacy` | 520 | | `oracle_policyengine` | 337 | -| **Total** | **33,175** | +| **Total** | **33,178** | diff --git a/tests/data/track_b/insured_status_examples.yaml b/tests/data/track_b/insured_status_examples.yaml index 4116d8730..70bca2a07 100644 --- a/tests/data/track_b/insured_status_examples.yaml +++ b/tests/data/track_b/insured_status_examples.yaml @@ -201,9 +201,9 @@ examples: endpoint, giving 20/10. RS 00301.140 assigns a post-1977 QC to any quarter of its year if insured status would be met, and both placements insure, so the printed figures are placement-dependent intermediate counts, not an - erratum. The - first onset's 14 quarters and 7 QCs reproduce; the first record holds 9 QCs - there, of which the example says Joseph requires and has 7. + erratum. The first onset's 14 quarters and 7 QCs reproduce; the first + record holds 9 QCs there, of which the example says Joseph requires and + has 7. implemented: elapsed_quarters: 20 required_qcs: 10 @@ -590,13 +590,14 @@ examples: allocated_earnings_difference: '100' qcs_both_readings: 3 coverage: source_ambiguity - note: The capture labels10900 as SEI but prints3600 for each of3 quarters. Literal - already-covered SEI gives10900/3. An unstated10800 ceiling for TYbeginning1973, - from RS00301.345 B.2.g and its example C.1, explains3600 each if10900 meant net - earnings before the ceiling. Both readings are executed; neither an arithmetic - erratum nor the omitted ceiling is established by the capture. Both yield3QCs - and differ by100 in allocated earnings. Private helper consumes already-covered - SEI; public short taxable years remain refused. + note: The capture labels $10,900 as SEI but prints $3,600 for each of three + quarters. Literal already-covered SEI gives $10,900/3. An unstated $10,800 + ceiling for the taxable year beginning in 1973, from RS 00301.345 B.2.g and + its example C.1, explains $3,600 each if $10,900 meant net earnings before + the ceiling. Both readings are executed; neither an arithmetic erratum nor + the omitted ceiling is established by the capture. Both yield three QCs and + differ by $100 in allocated earnings. Private helper consumes + already-covered SEI; public short taxable years remain refused. test_node: tests/test_track_b_insured_status_qc.py::test_rs00301_340_short_year_source_erratum_is_not_imitated execution_scope: allocation_helper public_refusal_reason: short_taxable_year_unsupported diff --git a/tests/test_track_b_insured_status_classification_oracle.py b/tests/test_track_b_insured_status_classification_oracle.py index 7f76136dd..7eba95533 100644 --- a/tests/test_track_b_insured_status_classification_oracle.py +++ b/tests/test_track_b_insured_status_classification_oracle.py @@ -875,8 +875,18 @@ def test_classification_oracle_historical_boundary_lattice(flags): # absent/UNKNOWN side of the declaration boundary, not a malformed # Person constructor on the established side. established = onset < _fra(date(birth_year, 2, 2)).replace(day=1) + # 404.321(b) ends the 1890 cohort's prior by January 1955, the month + # before it attains 65, and a later declared end is an input error, + # so the lattice declares that end. + fra_end = _fra(date(birth_year, 2, 2)).replace(day=1) - timedelta( + days=1 + ) periods = ( - (rule.DisabilityPeriod(date(1952, 7, 1), date(*prior_end)),) + ( + rule.DisabilityPeriod( + date(1952, 7, 1), min(date(*prior_end), fra_end) + ), + ) if prior_end is not None else () ) diff --git a/tests/test_track_b_insured_status_fix_round_23.py b/tests/test_track_b_insured_status_fix_round_23.py index 2ad52066c..3fdd5a74b 100644 --- a/tests/test_track_b_insured_status_fix_round_23.py +++ b/tests/test_track_b_insured_status_fix_round_23.py @@ -287,6 +287,78 @@ def test_an_ended_current_period_counts_as_the_prior_it_becomes( assert _dli(_computed(listed, years, M1_MONTH)) == _dli(row.result) +def test_a_period_begun_in_the_age_31_quarter_rests_on_paragraph_d(): + # She attains 31 on 2006-02-14, in 2006Q1, the quarter of her January 20 + # onset, so 404.130(c)(1) fails there and 404.130(d)(1) finds her + # disabled again at 31. Her prior rested on 404.130(c) alone, so + # 404.130(d) counts the 40 quarters from 1996Q2 less the ten inside the + # prior after its first: 17 QCs (three in 1996, the two of 1997 in Q1 + # and Q2, and twelve from 2003) meet half of 30, and the period begins + # on the onset day. + prior = i.DisabilityPeriod( + date(1997, 4, 1), date(1999, 12, 31), special_insured=True + ) + person = _ended( + date(1975, 2, 15), date(2006, 1, 20), date(2007, 12, 31), prior + ) + month = date(2008, 1, 1) + annual = {1996: 4, 1997: 2, 2003: 4, 2004: 4, 2005: 4} + result = _computed(person, history(person, month, annual), month) + found = result.disability + assert result.current_disability_period_start == date(2006, 1, 20) + assert (found.insured, found.rule, found.qualifying_quarter) == ( + True, + "subsequent_special", + date(2006, 1, 1), + ) + assert (found.qc_count_lower, found.required) == (17, 15) + assert _dli(result) == (date(2008, 3, 31), date(2008, 3, 31), True) + + +def test_an_open_flag_keeps_paragraph_b_where_every_placement_meets_it(): + # Her listed prior leaves the flag open, but 404.130(b) holds at the + # 2007Q3 onset quarter on every placement. Counting the prior's + # quarters, as 404.130(f) allows where that helps, the 40 quarters from + # 1997Q4 hold 24 QCs, or 25 when her one 2007 QC comes before Q4, and + # leaving them out still leaves at least 22. So the period never rested on + # 404.130(c) alone, 404.130(d) doesn't reach the quarters after it, and + # 20 of 40 last holds at 2012Q2. Read as 404.130(c) alone, the open flag + # would bring in 404.130(d) more than 40 quarters after 21, where the + # readings of its cap differ and the record refuses. + prior = i.DisabilityPeriod(date(2002, 3, 19), date(2006, 1, 31)) + person = _ended( + date(1976, 12, 8), date(2007, 7, 5), date(2008, 1, 31), prior + ) + month, exit_month = date(2017, 3, 1), date(2008, 5, 1) + annual = { + 1996: 4, + 1997: 4, + 1998: 3, + 1999: 2, + 2000: 1, + 2001: 4, + 2002: 2, + 2004: 4, + 2005: 3, + 2006: 4, + 2007: 1, + 2008: 4, + } + years = history(person, month, annual, end=exit_month) + result = _computed( + person, years, month, test=DISABILITY, coverage_end_month=exit_month + ) + found = result.disability + assert result.current_disability_period_start == date(2007, 7, 5) + assert (found.insured, found.rule, found.qualifying_quarter) == ( + True, + "disability_20_of_40", + date(2007, 7, 1), + ) + assert (found.qc_count_lower, found.required) == (25, 20) + assert _dli(result) == (date(2012, 6, 30), date(2012, 6, 30), False) + + # A period that shares the quarter a prior ended in. JANE = i.DisabilityPeriod( @@ -735,6 +807,22 @@ def test_a_man_who_reached_62_before_1973_counts_to_65(): ) +def test_a_death_after_the_query_keeps_the_living_count(): + # On 1971-12-01 he is alive unless he died by that day, so a death later + # that month leaves 404.110(b)(2)(iv)'s count to 1972, and a death that + # day ends it at 1970 (404.110(b)(3)). + month = date(1971, 12, 1) + for died, expected in ( + (date(1971, 12, 2), (False, 22)), + (date(1971, 12, 15), (False, 22)), + (date(1971, 12, 1), (True, 20)), + ): + person = _person(date(1908, 7, 1), sex=MALE, death_date=died) + years = history(person, month, {y: 1 for y in range(1951, 1971)}) + fully = _computed(person, years, month, test=FULLY).fully + assert (fully.insured, fully.required) == expected, died + + # A flagged prior needs one placement for both halves. @@ -1144,18 +1232,24 @@ def test_each_published_first_onset_reproduces( def test_declared_dates_past_the_statutory_end_are_input_errors(): - # 404.321(b) ends a period by the month before FRA, June 2016 for a - # birth in June 1950. + # 404.321(c)(1) ends a period by the month before FRA. A June 1950 birth + # attains FRA in June 2016, so a period ends by 2016-05-31, and the end + # binds the current period and a listed prior alike. + birth = date(1950, 6, 15) for end, valid in ( (date(2016, 5, 31), True), (date(2016, 6, 30), False), (date(2017, 12, 31), False), ): + prior = i.DisabilityPeriod(date(2010, 1, 1), end) if valid: - _ended(date(1950, 6, 15), date(2010, 1, 15), end) + _ended(birth, date(2010, 1, 15), end) + _person(birth, prior) continue with pytest.raises(i.InvalidFamilyInput, match="statutory FRA end"): - _ended(date(1950, 6, 15), date(2010, 1, 15), end) + _ended(birth, date(2010, 1, 15), end) + with pytest.raises(i.InvalidFamilyInput, match="statutory FRA end"): + _person(birth, prior) @pytest.mark.parametrize( diff --git a/tests/test_track_b_insured_status_fix_round_3_periods.py b/tests/test_track_b_insured_status_fix_round_3_periods.py index 11c8ad235..926441ae5 100644 --- a/tests/test_track_b_insured_status_fix_round_3_periods.py +++ b/tests/test_track_b_insured_status_fix_round_3_periods.py @@ -227,7 +227,10 @@ def test_fra_date_and_quarter_match_independent_act_calendar(year, month, day): ) -def test_prior_period_is_capped_at_fra_for_status_and_requirement_helper(): +def test_prior_period_ends_by_fra_for_status_and_requirement_helper(): + # She attains FRA in January 2027, so 404.321(c)(1) ends a period by + # 2026-12-31. A later declared end is an input error (round 23; this + # round capped it), and the period that ends there sets both results. birth = date(1960, 1, 2) common = dict( birth_date=birth, @@ -238,21 +241,27 @@ def test_prior_period_is_capped_at_fra_for_status_and_requirement_helper(): sspa211_provenance=OBSERVED, rib_entitlement_month=date(2028, 10, 1), ) - overlong = i.Person( + with pytest.raises(InvalidFamilyInput, match="statutory FRA end"): + i.Person( + **common, + prior_disability_periods=( + i.DisabilityPeriod(date(2026, 1, 15), date(2028, 9, 30)), + ), + ) + person = i.Person( **common, prior_disability_periods=( - i.DisabilityPeriod(date(2026, 1, 15), date(2028, 9, 30)), + i.DisabilityPeriod(date(2026, 1, 15), date(2026, 12, 31)), ), ) - assert overlong.prior_disability_periods[0].end == date(2026, 12, 31) month = date(2028, 10, 1) - years = history(overlong, month, {y: 4 for y in range(2016, 2026)}) + years = history(person, month, {y: 4 for y in range(2016, 2026)}) result = i.insured_status( - overlong, years, month, test=i.InsuredTest.CURRENTLY + person, years, month, test=i.InsuredTest.CURRENTLY ) assert not result.currently.insured assert result.currently.qc_count_lower == 5 - assert i.fully_insured_requirement(overlong, month) == 40 + assert i.fully_insured_requirement(person, month) == 40 @settings(max_examples=12, deadline=None) @@ -326,17 +335,24 @@ def test_every_supplied_prior_period_has_the_statutory_fra_cap( birth = date(birth_year, birth_month, birth_day) fra = _act_fra(birth) cap = fra.replace(day=1) - timedelta(days=1) + start = cap.replace(year=cap.year - 2, day=1) person = i.Person( birth, - prior_disability_periods=( - i.DisabilityPeriod( - cap.replace(year=cap.year - 2, day=1), - cap.replace(year=cap.year + extra_years, day=1), - ), - ), + prior_disability_periods=(i.DisabilityPeriod(start, cap),), prior_disability_periods_provenance=OBSERVED, ) assert person.prior_disability_periods[0].end == cap + # A declared end past the cap is an input error (round 23), from the + # first day of the FRA month on. + for end in ( + cap + timedelta(days=1), + cap.replace(year=cap.year + extra_years, day=1), + ): + with pytest.raises(InvalidFamilyInput, match="statutory FRA end"): + replace( + person, + prior_disability_periods=(i.DisabilityPeriod(start, end),), + ) with pytest.raises(InvalidFamilyInput): replace( person, diff --git a/tests/tier_counts.json b/tests/tier_counts.json index 0d1388c5d..0783a0027 100644 --- a/tests/tier_counts.json +++ b/tests/tier_counts.json @@ -1,7 +1,7 @@ { "schema_version": 1, "counts": { - "unit": 26320, + "unit": 26323, "artifact": 4527, "integration_psid": 1471, "reproduction_legacy": 520, From f32d881207db59acb3ec13818f70ea63d258174b Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Tue, 3 Nov 2026 15:57:05 -0500 Subject: [PATCH 43/46] Scan down from the query for the stress oracle's date last insured (#562) The stress oracle's `last_insured` tested every quarter from the first credit through the query and kept the latest one that insures an onset. It now scans down from the query and stops at the first insured quarter. The stress module ran about an hour on CI, enough to push shard 4 past its time limit. Locally its first 40 tests drop from 1,008 to 164 CPU seconds, and all 52 pass in under six minutes. `full_scan_last_insured` keeps the old scan, and `test_status_stress_last_insured_matches_a_full_scan` checks that both scans return the same quarter. The test draws records from the base, entitlement-month, under-31 and subsequent-special generators. On two credit placements of each, it compares the scans with and without the declared periods, with and without the subsequent-special route, and under both readings. An upward scan that keeps the first insured quarter fails it, and so does a downward scan that skips the query quarter. The design note names the test, and the unit tier rises to 26,324. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 10 ++++ tests/README-tiers.md | 2 +- ...st_track_b_insured_status_status_stress.py | 58 ++++++++++++++++++- tests/tier_counts.json | 2 +- 4 files changed, 68 insertions(+), 4 deletions(-) diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index 9255558b0..ec46628b0 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -2148,6 +2148,16 @@ The invariants added in this round are executed by these tests: - the DISABILITY refusal tracks the exact aggregate (`test_disability_refusal_tracks_the_exact_aggregate`). +The oracle's `last_insured` scans down from the query quarter and stops at +the first quarter that insures an onset, so it returns the latest one and +skips the earlier quarters. +`test_status_stress_last_insured_matches_a_full_scan` checks it against +`full_scan_last_insured`, which tests every quarter from the first credit +through the query. The test draws records from the base, entitlement-month, +under-31 and subsequent-special generators. On two credit placements of +each, it compares the scans with and without the declared periods, with and +without the subsequent-special route, and under both readings. + ## Round 16 diagnostics on the reported start Verification class: statutory conformance on invented declarations only. diff --git a/tests/README-tiers.md b/tests/README-tiers.md index b08f87794..a08e410f4 100644 --- a/tests/README-tiers.md +++ b/tests/README-tiers.md @@ -39,7 +39,7 @@ pytest --collect-only -q -m oracle_policyengine | tail -1 | Tier | Tests at HEAD | |---|---:| -| `unit` | 26,323 | +| `unit` | 26,324 | | `artifact` | 4,527 | | `integration_psid` | 1,471 | | `reproduction_legacy` | 520 | diff --git a/tests/test_track_b_insured_status_status_stress.py b/tests/test_track_b_insured_status_status_stress.py index b25150351..08c7eb748 100644 --- a/tests/test_track_b_insured_status_status_stress.py +++ b/tests/test_track_b_insured_status_status_stress.py @@ -41,7 +41,7 @@ import calendar import random from datetime import date, timedelta -from itertools import combinations, product +from itertools import combinations, islice, product import pytest from hypothesis import assume, example, given, settings @@ -170,7 +170,27 @@ def disability( def last_insured(birth, credits, at, periods, blind, special, reading): - """Latest quarter through the query that insures a potential onset.""" + """Latest quarter through the query that insures a potential onset. + + The scan runs down from the query and returns the first insured quarter + it meets. + """ + return next( + ( + candidate + for candidate in range(at, min(credits, default=at) - 1, -1) + if disability( + birth, credits, candidate, periods, blind, special, reading + ) + ), + None, + ) + + +def full_scan_last_insured( + birth, credits, at, periods, blind, special, reading +): + """``last_insured`` by checking every quarter, for the differential test.""" return max( ( candidate @@ -1554,3 +1574,37 @@ def test_status_stress_every_history(seed, unknown_end, test): case = {**declaration(seed), "prior": ()} assume(sum(1 for _ in placements(case["annual"])) <= 96) check_every_history(case, unknown_end, test) + + +@settings(max_examples=40, deadline=None, derandomize=True) +@given( + seed=st.integers(0, 2**32 - 1), + make=st.sampled_from( + ( + declaration, + with_entitlement, + under_31_declaration, + subsequent_declaration, + ) + ), +) +def test_status_stress_last_insured_matches_a_full_scan(seed, make): + # The oracle's downward scan must date every filling as the full scan does. + case = make(seed) + current = case["prior"] + ((case["onset"], case["ending"]),) + for credits in islice(placements(case["annual"]), 2): + for periods in (current, ()): + for special in (False, True): + for reading in READINGS: + args = ( + case["birth"], + credits, + quarter(case["month"]), + periods, + case["blind"], + special, + reading, + ) + assert last_insured(*args) == full_scan_last_insured( + *args + ), (case, args) diff --git a/tests/tier_counts.json b/tests/tier_counts.json index 0783a0027..1776a00b5 100644 --- a/tests/tier_counts.json +++ b/tests/tier_counts.json @@ -1,7 +1,7 @@ { "schema_version": 1, "counts": { - "unit": 26323, + "unit": 26324, "artifact": 4527, "integration_psid": 1471, "reproduction_legacy": 520, From 0c39ea4ba81c3b8157765bbd039548b87bd162a6 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Tue, 3 Nov 2026 17:21:08 -0500 Subject: [PATCH 44/46] Refuse by name where a completion leaves a listed prior unsupported (#562 round 24) On an established current period, the rule raises InvalidFamilyInput only where every completion of its UNKNOWN years would. At fc689ecb it raised one on records that only some completions support, and dropped their rows (the review's medium). _refuse_undecided_priors now checks each flagged listed prior, and each from July 1952 through 1955, on every completion of the years open by its start, and each other listed prior on lower credits. It refuses with unknown_earnings_years_decide_status where a completion leaves a prior unsupported. _refuse_boundary_completions refuses where some completion could exceed 4,096 boundary assignments, since a middle count can have more than either bound. The new round 24 module adds 64 unit tests: worked records for each basis, the guards' thresholds, a soundness property over every completion and a differential property for the lower-credit shortcut. Each of round 24's 28 mutations fails a named test, and the note records the round. In the issue draft, the encoding now refuses where some completion leaves a listed prior unsupported. The examples file gives the second RS 00301.340 short-year note back its dollar signs, and the tier README's total now sums its rows, where f32d8812 had left it at 33,178. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 198 ++++++- .../track_b_insured_status_rulespec_issue.md | 23 +- .../track_b/insured_status.py | 131 +++- tests/README-tiers.md | 4 +- .../data/track_b/insured_status_examples.yaml | 7 +- ...est_track_b_insured_status_fix_round_24.py | 559 ++++++++++++++++++ tests/tier_counts.json | 2 +- 7 files changed, 893 insertions(+), 31 deletions(-) create mode 100644 tests/test_track_b_insured_status_fix_round_24.py diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index ec46628b0..2f92af8aa 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -215,9 +215,10 @@ Maximum credits decide the monotone insured-by-that-date question. Every prior period ends before onset, and a period may begin in the quarter a prior ended, so no derived start overlaps a prior period (round 23). Only when all routes and feasible fillings are impossible can the rule -raise `InvalidFamilyInput` before any coverage refusal, and a listed prior -that no completion supports refuses by name first (round 23; see the -refusal order below). On the ordinary +raise `InvalidFamilyInput` before any coverage refusal, and then only where +every completion would: a listed prior that some completion leaves +unsupported, or a completion that could exceed the boundary cap, refuses by +name first (rounds 23 and 24; see the refusal order below). On the ordinary supported QC surface, fewer than six maximum feasible lifetime QCs proves impossibility: 404.130(a) requires fully insured status, and 404.110(b)(1) says, "You need at least 6 QCs but @@ -668,7 +669,13 @@ current period as well, so it refuses by its own name after any deferred conversion refusal and before the input error. A fully-route flag that can carry the prior suppresses that refusal. The same check precedes the UNKNOWN-earnings refusal of an established period -whose validity rests on unknown credits (round 23). With no deferred +whose validity rests on unknown credits (round 23). An input error drops the +row, so it also needs each listed prior's support on every completion: where +some completion of the years open by a flagged or pre-1956 prior's start, or +any other prior's lower credits, leave it unsupported, the record refuses +with `unknown_earnings_years_decide_status`, and where some completion could +exceed 4,096 boundary assignments, with +`disability_boundary_assignments_unsupported` (round 24). With no deferred reason, the existing specialist, date, applicability, and requested-status checks follow. In the requested-status checks, a positive ordinary DISABILITY witness does not bypass the observable alternate route when @@ -686,7 +693,7 @@ input. An input error propagates and creates no row. | Trigger | Reason code | | --- | --- | -| Unknown-year bounds decide a requested status differently, an UNKNOWN year decides whether 404.130(b) began the current period where that moves the date last insured, or a flagged prior's first quarter has more than 4,096 completions | `unknown_earnings_years_decide_status` | +| Unknown-year bounds decide a requested status differently, an UNKNOWN year decides whether 404.130(b) began the current period where that moves the date last insured, or a flagged prior's first quarter has more than 4,096 completions, or, where no completion can insure an established current period, some completion leaves a listed prior unsupported or more than 4,096 completions stand open by its start | `unknown_earnings_years_decide_status` | | Unknown prior periods may change a requested status | `unknown_prior_disability_periods_decide_status` | | Unknown current establishment may change a requested status | `unknown_current_disability_period_decides_status` | | Any candidate end quarter for an UNKNOWN current ending changes a requested status | `ongoing_disability_period_end_decides_status` | @@ -708,7 +715,7 @@ input. An input error propagates and creates no row. | Earnings require an increment after 2027 | `qc_amount_year_unsupported` | | Query before 1968; blind query before 1973; a query before May 1983 for the holder of a flagged prior whose age-31 quarter begins before then (round 23: 404.130(c) still covers an onset before 31) | `entitlement_before_1968_unsupported`, `blindness_before_1973_unsupported`, `subsequent_special_before_1983_unsupported` | | A subsequent-special period past 40 counted quarters where half the whole period and 20 of the last 40 give different results | `subsequent_special_long_period_unsupported` | -| More than 4,096 disability-boundary combinations, a first start that placement or prior treatment can move with no one filling supporting the returned result, a lower date some ending can't reach on a filling with the reported start, a status or lower date some annual placement doesn't attain with no period in force under UNKNOWN priors or UNKNOWN establishment, a listed prior that annual placement decides where an UNKNOWN year stands open or no filling that keeps the prior attains the result, a listed prior that no completion supports (before any input error the record would raise), or a date last insured that turns on whether annual placement let 404.130(b) begin the current period, after every credit-count proof applicable to the surviving flag classes and foreign-credit declaration | `disability_boundary_assignments_unsupported` | +| More than 4,096 disability-boundary combinations on the record or, where no completion can insure an established current period, on some completion of its UNKNOWN years, a first start that placement or prior treatment can move with no one filling supporting the returned result, a lower date some ending can't reach on a filling with the reported start, a status or lower date some annual placement doesn't attain with no period in force under UNKNOWN priors or UNKNOWN establishment, a listed prior that annual placement decides where an UNKNOWN year stands open or no filling that keeps the prior attains the result, a listed prior that no completion supports (before any input error the record would raise), or a date last insured that turns on whether annual placement let 404.130(b) begin the current period, after every credit-count proof applicable to the surviving flag classes and foreign-credit declaration | `disability_boundary_assignments_unsupported` | The round-3 observable-trigger audit covers every `CoverageCondition`. An explicit condition continues to refuse under its own reason when the @@ -848,7 +855,7 @@ to a statutory sentence that does not state it. | I5. A supplied `special_insured` prior period begins before the age-31 attainment quarter. | B404.130(d)(1): a prior period "began before age 31" and the worker "were only insured under paragraph (c)"; (c)(1) requires age 31 not yet attained. A216(i)(3)(B)(iii) expressly uses "before the quarter" of age 31. The flag declares this particular adjudicated young-worker route, not every possible special credit regime. | | I6. An alien worker's actual pre2004 SSN assignment conflicts with declared SSPA applicability; birth on/after January 1, 2004 conflicts with declared exemption. Both never-assigned and an assigned SSN, or assignment before birth, remain invalid. A worker born before 2004 may pair a post2003 assignment or never-assigned status with an adjudicated exemption. | RS .102 B.1 says an alien assigned an SSN before 2004 "is exempt", including a nonwork SSN. B.3.b says, "If an alien worker could have legitimately been assigned an SSN before 1/1/2004, the worker is exempt from the requirements of section 211 of the SSPA." Its wrong-number SS-5 scenario issued another person's number "instead of assigning the alien worker their own SSN". Thus observed or convention-filled exemption overrides either later-assignment or never-assigned presumptions when legitimate pre2004 assignment was possible. Birth on/after January 1, 2004 rules out that exception independently of the assignment record. B.4.b's worker without an SSN "is nevertheless considered to meet the work SSN requirement" when work-authorized; meeting that requirement alone supplies no exemption. | | I7. Explicit quarterly QCs cannot occur before birth, after the query/coverage-end quarter, or after the death quarter; positive quarterly wages cannot occur before birth or after the query/coverage-end quarter. Every required coverage year is declared exactly once through the earliest query, exit, or death year. | A213(a)(2)(B)(i), (v): "no quarter after the quarter in which an individual dies" and "no quarter shall be counted ... prior to the beginning of such quarter"; B404.146(a)-(b) agree. Wages paid after the death quarter still count toward that year's total under A213(a)(2)(B)(ii), so they contradict nothing (round 23). Birth and supplied-record exit caps on dated rows, complete years, and no implicit zeros are interface premises. An annual count is undated, so neither cap bars a quarter of its year (round 23). Specialist earned-basis or additional-credit declarations remain refusals and do not reinterpret an explicit ordinary covered-quarter declaration. | -| I8. A declared current establishment is invalid only after the shared possibility check excludes every route and every feasible prior/earnings filling. One ordinary filling must satisfy its insured start, recovery or administrative end, and continuity constraints together. | C320(b)(2) requires insured disability "in the calendar quarter in which you became disabled, or in a later calendar quarter"; C321(a) chooses the first such quarter. B404.130(a) supplies four ordinary rules and RS .480 supplies the alternate historical rule. The start horizon uses an inferred recovery month when I14 permits one, otherwise the declared end, together with continuity/query/death/FRA caps. Maximum credits establish only monotone insurance by that fixed horizon; no derived start can overlap a prior (I4). A listed prior that no completion supports refuses by name before this input error (round 23). An ordinary start found only through placement or treatment search establishes possibility and retains a named refusal; it does not select a status witness. An ordinary or alternate witness after the horizon cannot supply possibility. Foreign credits and the flag classes determine which credit-count proofs apply, in the refusal order above, before any alternate or boundary enumeration. The alternate's 20/40 exclusion instead uses U10's earliest date shared by every completion; a later witness cannot prove impossibility under every defensible reading of RS .480 A. | +| I8. A declared current establishment is invalid only after the shared possibility check excludes every route and every feasible prior/earnings filling. One ordinary filling must satisfy its insured start, recovery or administrative end, and continuity constraints together. | C320(b)(2) requires insured disability "in the calendar quarter in which you became disabled, or in a later calendar quarter"; C321(a) chooses the first such quarter. B404.130(a) supplies four ordinary rules and RS .480 supplies the alternate historical rule. The start horizon uses an inferred recovery month when I14 permits one, otherwise the declared end, together with continuity/query/death/FRA caps. Maximum credits establish only monotone insurance by that fixed horizon; no derived start can overlap a prior (I4). A listed prior that some completion leaves unsupported, or a completion that could exceed the boundary cap, refuses by name before this input error (rounds 23 and 24). An ordinary start found only through placement or treatment search establishes possibility and retains a named refusal; it does not select a status witness. An ordinary or alternate witness after the horizon cannot supply possibility. Foreign credits and the flag classes determine which credit-count proofs apply, in the refusal order above, before any alternate or boundary enumeration. The alternate's 20/40 exclusion instead uses U10's earliest date shared by every completion; a later witness cannot prove impossibility under every defensible reading of RS .480 A. | | I9. Except for blindness with a fully-route flag, fewer than six maximum feasible QCs by the immutable start horizon proves current establishment impossible after foreign credits, credit-route flags, and unresolved raw-earnings flags have preserved their possible routes. | B404.110(b)(1): "You need at least 6 QCs but not more than 40 QCs"; B404.130(a): "you must be fully insured". The flag table supplies each exception's captured premise. A record composed entirely of direct final QC declarations (`qc_count` or `qc_quarters`) and UNKNOWN years fixes or bounds all admissible final credits from RR compensation and fiscal/short taxable-year allocation. This is the direct-credit input contract, not a claim that ordinary RSDI credits exhaust freeze-only military credits: B404.133 expressly supplies the latter, so `MILITARY_CREDITS` remains a separate credit route even with direct rows. Any raw row leaves the raw-earnings route unresolved. Period exclusions alone cannot add ordinary QCs. RS .480 A separately requires 20 QCs and the explicit `DISABILITY_BEFORE_1956` flag adds no route beyond the automatic alternate, so it cannot rescue a below-six declaration. Fully-route flags replace only the fully insured prerequisite; nonblind recent rules retain the universal horizon floor in I17, even under UNKNOWN prior history. Blindness with a fully-route flag bypasses that floor under 404.130(e). No ordinary floor applies to the unmodeled foreign-credit route (U11). | | I10. The supported calendar, mandatory historical sex, and explicit establishment declaration must be supplied: birth years 1870–9900, query years through 9990, sex for births before January 2, 1913, and establishment provenance whenever onset is present. | These are interface-domain requirements. B404.110(b)(2) and .132 apply different historical male/female endpoints; B404.110(c) excludes only a period "we established for you". Missing facts are not inferred. Calendar limits reserve space for date arithmetic and assert no legal incapacity outside the implementation domain; alternative credit routes cannot supply missing declared facts. | | I11. A continues-through observation requires established disability, cannot precede medical onset or the first feasible insured start, cannot exceed the pre-FRA or death boundary, and cannot follow a declared administrative end. | C320(b)(2) and C321(a) require the insured start; A216(i)(2)(D) and C321(c) bound the period's end. A declaration that a period was in force on a date requires that date to lie within one possible period. This is a dated observation, not an asserted ending; a date later than the query is allowed. Provenance and convention identifiers follow the existing fact schema. | @@ -867,7 +874,7 @@ to a statutory sentence that does not state it. | U2. UNKNOWN current establishment needs no new-period alternative if there is no medical onset or onset is at/after the statutory latest starting month. | A216(i)(2)(A)-(D) and C321 prohibit a period without disability or a nonempty pre-FRA interval. This removes an impossible new-period alternative only; it does not remove UNKNOWN prior history or an existing period's UNKNOWN administrative end. | | U3. With unknown prior/current periods, true ordinary FULLY and CURRENTLY status under favorable all-period disregard decides true. A DISABILITY witness must also survive any current-establishment completion that ends the disability before that witness. Every annual placement must attain the status at the quarter it reports with no period in force, because a period's own start can rule a filling out (round 19). | C320(a): "If benefits ... would be denied or reduced because of a period of disability, the period of disability will not be taken into consideration." B404.130(f) also permits counting all prior quarters if favorable. RS .120 requires all periods used or all disregarded; selective exclusions are not assumed. Specialist credit regimes are refused first. | | U4. With unknown periods, fewer than six maximum QCs feasible by the immutable horizon proves establishment impossible after routes adding undeclared credits are excluded, except for blindness with a fully-route flag; it supplies no foreign-credit impossibility proof. | B404.110(b)(1) and B404.130(a) supply the ordinary six-QC prerequisite. U3's disregard cannot manufacture credits. UNKNOWN prior history disables both I15 and I16; current nonblindness cannot exclude a past blind prior. The separate emptiness proof tests the earliest prior as blind, and proves emptiness only if no earlier quarter can supply fully insured status or the alternate. It can preserve a fully-route refusal with empty recent windows only after the universal six-QC horizon floor clears (I17). Foreign credits, credit-route flags, and raw-earnings flags outside a complete direct envelope also preserve named refusals. The direct-envelope contract and declared pre1956 alternate still obey I9; that alternate flag adds no route beyond B4. Blindness alone supplies no credits and does not replace the ordinary fully insured prerequisite. | -| U5. UNKNOWN earnings decide a requested Boolean only if all lower/upper ordinary earnings witnesses agree, under the permitted fixed-period/all-period treatments; an uncertain established start refuses only after at least one feasible filling survives. | B404.143 credits one QC for each increment, maximum four; B404.130 and .146 supply assignment/exclusion rules. Adding ordinary QCs cannot invalidate a fixed treatment. A derived start cannot be silently held fixed when the completion changes it. If a lower or upper representative cannot construct the declared period, but another single filling meets its end and continuity constraints, the public result is `unknown_earnings_years_decide_status`, unless a listed prior that no completion supports refuses first (round 23). If no ordinary filling can qualify by the declared end and all independent routes are impossible, it is an input error and creates no row. A deferred raw-conversion row uses temporary unknown fillings only for possibility, then retains its conversion refusal. Specialist possibilities and administrative-end candidates are considered separately. | +| U5. UNKNOWN earnings decide a requested Boolean only if all lower/upper ordinary earnings witnesses agree, under the permitted fixed-period/all-period treatments; an uncertain established start refuses only after at least one feasible filling survives. | B404.143 credits one QC for each increment, maximum four; B404.130 and .146 supply assignment/exclusion rules. Adding ordinary QCs cannot invalidate a fixed treatment. A derived start cannot be silently held fixed when the completion changes it. If a lower or upper representative cannot construct the declared period, but another single filling meets its end and continuity constraints, the public result is `unknown_earnings_years_decide_status`, unless a listed prior that no completion supports refuses first (round 23). If no ordinary filling can qualify by the declared end and all independent routes are impossible, it is an input error and creates no row, provided each listed prior holds on every completion and no completion can exceed the boundary cap; otherwise it refuses by name (round 24). A deferred raw-conversion row uses temporary unknown fillings only for possibility, then retains its conversion refusal. Specialist possibilities and administrative-end candidates are considered separately. | | U6. UNKNOWN administrative end decides a status only when every end-quarter candidate from start through query/cap, plus permitted continuation, agrees, after applying any continuity lower bound. | A216(i)(2)(D) uses "whichever ... is the earlier"; C321(c)(3) includes "the last month for which you received benefits" after substantial gainful activity. Medical continuity cannot exclude early ends; a dated administrative continuity observation can. FRA/death caps limit the latest candidate and do not turn the unknown into a fact. Both ending and prior-history unknown facts remain disclosed when both are missing; UNKNOWN prior history uses the universal envelopes rather than inventing a derived current period to enumerate. The unchanged completion enumeration can include early endings rejected by I14 if declared concretely. Agreement across that larger set still implies agreement across every valid completion, while disagreement can preserve an extra refusal. An actual supplied end keeps its declared-date semantics; known ending provenance requires an ending date. | | U7. UNKNOWN SSPA applicability preserves an ordinary QC-only false status, but never a QC-only true status. | RS .102 B.2 says the worker "must meet one of the following additional requirements" and may fail "even if" the QC requirement is met. Applicability can remove ordinary insurance and cannot supply missing QCs. Known applicability retains adjudication refusal; any separate specialist path is refused first. | | U8. With UNKNOWN prior history, a known current period's start is certain onset only if the lower credits insure the onset on every annual placement with no period in force (round 19); otherwise the start stays unknown. | A216(i)(2)(C) and C321(a) make insured onset the earliest legal start. C320(a)'s disregard permits that witness, and no route can move this period before medical onset. Other potentially valid histories prevent an impossibility error but do not fabricate a start. | @@ -888,7 +895,7 @@ to a statutory sentence that does not state it. | B8. For a nonblind ordinary worker with no prior period, no DLI can lie more than 39 quarters after the last credited quarter. | B404.130(b)(2) requires "at least 20 QCs in the 40-quarter period ... ending with that quarter". After 39 later quarters no original QC remains. Blindness and prior-period special/exclusion routes disable this search shortcut; flagged or observable specialist routes refuse. | | B9. With unknown periods the disregard DLI is a lower bound and the permitted query/FRA/death horizon is the upper bound; unknown SSPA applicability reduces any positive DLI lower bound to `None`. | C320(a) permits favorable disregard; B404.130(f) permits counting all prior-period quarters; RS .102 B.2 imposes an additional requirement. The bound does not infer a particular recovery or history. Exemption can recover the ordinary upper witness but cannot exceed the calendar horizon. Round 19 requires every annual placement to reach the lower bound with no period in force, and refuses by name otherwise. | | B10. UNKNOWN-ending DLI bounds include every end candidate. With an unresolved ongoing end, known prior history, and frozen-exit future horizon beyond query, the named DLI-horizon refusal remains. | C321(c)'s alternative endings and RS .148's last qualifying quarter permit different historical DLI witnesses. The candidate extrema bound all declared endings; no recovery beyond the query is inferred. Refusal covers the unobserved future administrative fact. Round 17 requires every ending to reach the lower date on a filling with the reported start, and refuses by name otherwise. Under UNKNOWN priors every placement must reach it with no period in force, so no ending changes it (round 19). | -| B11. At most 4,096 combinations of disability endpoint assignments are searched exactly, after any applicable impossibility proof. | B404.143(b) and RS .230 permit favorable assignment; B404.130(f) makes credited endpoints decisive. Six-QC and I15's minimum-requirement checks precede `_boundary_variants`, including both alternate-path calls and UNKNOWN-prior-history feasibility. A remaining excess returns `disability_boundary_assignments_unsupported`; computational complexity is neither a statutory impossibility bound nor permission to retain an all-invalid declaration. | +| B11. The rule searches at most 4,096 combinations of disability endpoint assignments exactly, after any applicable impossibility proof. | B404.143(b) and RS .230 permit favorable assignment; B404.130(f) makes credited endpoints decisive. Six-QC and I15's minimum-requirement checks precede `_boundary_variants`, including both alternate-path calls and UNKNOWN-prior-history feasibility. A remaining excess returns `disability_boundary_assignments_unsupported`; computational complexity is neither a statutory impossibility bound nor permission to retain an all-invalid declaration. A middle count can have more assignments than either bound, so an input error also needs every completion's count within the cap (round 24). | | B12. Ordinary counted windows have 13 quarters for current insurance and 40 for ordinary disability; young/subsequent special windows require half their elapsed quarters after dropping an odd remainder, with a six-QC minimum. The young-worker window holds at most 39 quarters. A subsequent-special period past 40 quarters computes only where the Act's whole period and 404.130(d)(2)'s 20 of 40 agree (round 17). | B404.120(a) says "13-quarter period"; .130(b) says "20 QCs in the 40-quarter period"; .130(c)-(d) and A216(i)(3)(B) supply the half-quarter, odd-remainder, and 6/12 alternatives. Blindness uses only the fully insured prerequisite. A fully-route flag must still leave a recent-rule witness or possible automatic pre1956 alternate where I16 applies; the pre1956 flag adds no route beyond that alternate. Specialist paths retaining possibility receive their named refusal. | | B13. Indexed annual QC amounts are at least the prior year's statutory increment and the rounded indexed 1978 amount, with nearest-$10 rounding and $5 ties upward. | A213(d)(2) chooses "the larger of" the prior increment and indexed amount, rounded to "the next higher multiple of $10" at a $5 tie. This exact parameter calculation has no disability or specialist alternative; input-domain checks require positive NAWI and a statutory prior increment. | | B14. Declaring continuity never widens the administrative-end candidate set; every returned status and count envelope remains valid for every retained concrete ending. | C321(c)'s ending events still govern. Set intersection with ends on/after the observation can only remove candidates; it creates neither an ending nor a new credit. The universal envelope remains unchanged where other unknown facts require it. | @@ -3763,6 +3770,179 @@ These tests execute the invariants this round adds: insured status modules (`test_the_note_check_reads_only_the_note_and_insured_modules`). +## Round 24 an input error holds on every completion + +Verification class: statutory conformance on invented declarations only. This +correction admits no population, behavioral, payment, or forecast claim. An +independent reviewer of `fc689ecb` reported one medium, two lows and a nit (PR +#562 comment 6615437593). `f32d8812` then changed only the stress module, the +tier counts and this note, so the medium still held when a second reviewer +approved that head and left two nits and a low open (PR #562 comment +6616118566). Round 24 brings the interface, refused configurations and +premises sections above up to date. + +### A prior some completion leaves unsupported + +Round 23 refused by name where no completion supports a listed prior, since +such a record omits credits or facts that could insure the current period. An +input error drops the row, so the rule may raise one only where every +completion would. On a completion that leaves a listed prior unsupported, the +rule refuses by the prior's name and keeps the row. At `fc689ecb`, +`_prior_basis` looked for support on upper credits and `_flag_fits` on any +completion, so the rule raised `InvalidFamilyInput` on records that only some +completions support (medium). For example, a woman born 1950-02-02 has 16 QCs +from 1981 to 1984, a prior from 1990 and an established 2005 period. She needs +18 QCs for fully insured status at 1990Q1, so two must come from 1989. With +1989 UNKNOWN the rule dropped her row, though with none or one 1989 QC it +refuses by the prior's name. `_refuse_undecided_priors` now runs after +`_refuse_unsupported_priors` and refuses with +`unknown_earnings_years_decide_status` where some completion leaves a listed +prior unsupported +(`test_a_year_that_can_leave_an_unflagged_prior_unsupported_refuses`). With +four 1985 QCs, every completion supports the prior, and the rule still raises +the input error +(`test_a_prior_every_completion_supports_keeps_the_input_error`). + +`_refuse_undecided_priors` picks the completions it reads by the prior's basis: + +- For an unflagged prior from 1956, it reads lower credits, since the law sets + a minimum number of QCs for every basis such a prior can rest on. + `test_lower_credits_speak_for_every_completion_of_an_unflagged_prior` checks + that shortcut against a search of every completion on invented records. +- A flagged prior needs a special route to pass and 404.130(b) to fail at its + start. Too few QCs in a year open by then can leave the route unmet, and more + can meet 404.130(b), so it reads every completion of those years. For + example, a woman born 1965-06-15 has 18 QCs from 1983 to 1988. Four 1990 QCs + fill 1990Q1 and 1990Q2 and bring 404.130(b) to 20 at 1990Q2; with three in + 1987 instead, an empty 1990 leaves 404.130(c) a QC short + (`test_either_bound_of_a_start_year_can_unseat_a_flagged_prior`). The + reviewer's r6 mutation, which leaves the start year out of `_flag_fits`'s + completions, passed every module the reviewer ran (low), and now fails that + test. +- An unflagged prior from July 1952 through 1955 can rest on RS 00301.480 B.1, + a route a holder can lose by meeting 20 of 40 in a later quarter through + September 1960, so credits by its start can help or hurt it. Before 1978, QCs + fall in fixed quarters, so `_completions` makes a completion of each set of + an open year's quarters; agricultural QCs, which a test may place, support a + prior wherever every set they can fill does. For a woman born 1915-03-02 with + a 1953Q1 prior, a 1953Q1 QC meets 404.130(b) there. Without one, a 1953Q2 QC + brings 20 of 40 a quarter after the prior, and only the any-quarter reading + of RS 00301.480 A counts that quarter against B.1 + (`test_a_quarter_after_the_start_can_exclude_the_pre1956_route`). A count the + rule placed to suit each test would put that QC in 1953Q1 and hide the + completion. Credits after the start year move neither the prior's + first-quarter tests nor B.1's counts and only add to a later 20 of 40, so it + reads upper credits for those years + (`test_years_after_a_pre1956_start_count_at_their_upper_credits`). B.1 covers + no period that begins before July 1952, so for a prior from January 1952 it + reads lower credits (`test_a_prior_before_july_1952_rests_on_lower_credits`). +- Where a fully-route flag carries the prior on a completion, the record lacks + nothing there, as in round 23 + (`test_a_flag_that_carries_the_prior_keeps_the_input_error`). + +Past 4,096 completions, the rule refuses by their number +(`test_more_completions_than_the_cap_refuse_by_their_number`, +`test_completions_refuse_past_4096`). `_completions` lists each set of an open +year's quarters before 1978 and each count from 1978, and a deferred year keeps +its fixed quarters on every completion +(`test_completions_list_quarter_sets_before_1978_and_counts_after`, +`test_completions_keep_a_deferred_year_s_fixed_quarters`). + +### A middle completion past the boundary cap + +Round 24 also closes a gap that predates it. `_boundary_variants` refuses more +than 4,096 assignments of the QCs in years that hold a listed prior's first or +last quarter, and a year's assignments peak at a middle count: two QCs in four +open quarters have six, while none or four have one. So bounds within the cap +can hide a completion past it, and the rule refuses that completion by name. +For example, the rule raised `InvalidFamilyInput` on a woman born 1955-02-02 +with priors from October 1980, 1984 and 1988, each to the next March, two QCs +in each of 1980, 1981, 1984 and 1985, and 1988 and 1989 UNKNOWN. Two QCs in +each of those years give 46,656 assignments, and the rule refuses that +completion. `_refuse_boundary_completions` now counts every endpoint year with +its quarters open through death, which bounds every completion's worlds, and +refuses past the cap (`test_a_middle_completion_past_the_boundary_cap_refuses`, +`test_endpoint_years_within_the_cap_keep_the_input_error`, +`test_the_boundary_guard_refuses_only_past_4096`, +`test_known_endpoint_years_leave_the_cap_to_the_record`, +`test_the_boundary_guard_leaves_fixed_quarters_out`, +`test_the_boundary_guard_counts_no_quarter_after_death`). + +### Every completion of an input error + +`test_an_input_error_holds_on_every_completion` draws invented records with +listed priors, an established current period and one or two open years. +Wherever the rule raises `InvalidFamilyInput` on one, the test runs each +completion and checks that each raises one too. Two searches of 400 such +records outside the suite ran 10,427 and 9,407 completions and found no +violation; with `_refuse_undecided_priors` off, the first found 37. The draws +hold at most two priors, so none reaches the boundary cap, and the boundary +tests above cover it. + +### The other lows and nits + +- low: where only the third parse of 404.130(d)(2) insures, the rule still + computes DISABILITY false and raises `InvalidFamilyInput` on an established + period. The rule keeps that behavior until Max rules on the pattern in d1920. +- nit: the PR body's differentials bullet and its sentence on the registry's + captures now match the README. +- nit: the second RS 00301.340 short-year note + (`poms_340_possible_unstated_ceiling`) gets back its dollar signs and spaces. +- low: whether an RIB can begin in the month a holder born on the first + attains 62 still rests on Act 202(a)'s text, which no captured source holds, + so the check stays at the attainment month, as round 23's low 16 records. + +### Mutations + +Round 24's own 28 mutations undo one change each. `undecided_off` and +`undecided_call_dropped` skip `_refuse_undecided_priors`, and `guard_off` and +`guard_call_dropped` skip `_refuse_boundary_completions`. +`scan_flagged_on_lower`, `scan_pre1956_on_lower`, `unflagged_on_upper`, +`scan_every_prior` and `scan_window_from_1937` read the wrong credits for one +kind of prior; `scan_to_1960` and `scan_before_start_year` move the last open +year; `rescue_dropped` ignores a fully-route flag that carries the prior. Eight +change `_completions`: `completions_counts_only` and +`completions_sets_from_1979` treat a year before 1978 as a count, +`completions_last_exclusive`, `completions_sets_short` and +`completions_counts_short` drop a year, set or count, and +`completions_cap_inclusive`, `completions_drop_fixed` and +`completions_rest_at_lower` break the cap, a deferred year's fixed quarters and +the upper credits of later years. Six change the boundary guard: +`guard_no_skip`, `guard_inclusive`, `guard_ignores_death`, +`guard_upper_count_only`, `guard_lower_count_only` and +`guard_counts_fixed_quarters`. `flag_fits_before_start` replays the reviewer's +r6, and `prior_basis_inverted` makes an unflagged prior's basis fail where more +credits pass it. Each of the 28 failed a named round 24 test under the audit +hook, with no restricted open. `guard_off` passes the soundness property, whose +draws never reach the cap, and fails the boundary tests; `prior_basis_inverted` +fails the shortcut's differential property. Round 24's list keeps round 23's +and adds these 28; `precedence_possible` now drops only the +`_refuse_unsupported_priors` call that round 24's checks follow. + +With `f32d8812`'s `insured_status.py` in place of this round's, eight of the +tests that call the rule fail: the UNKNOWN records of the unflagged prior, both +flagged priors and the pre-1956 prior, the January 1952 prior, the completion +cap, the boundary record and the soundness property. On each of the first +seven, the rule raises `InvalidFamilyInput` there. + +These tests execute the invariants this round adds: + +- on an established current period, the rule raises `InvalidFamilyInput` only + where every completion of its UNKNOWN years would, and where some completion + leaves a listed prior unsupported, it refuses by name and the row keeps its + weight (`test_an_input_error_holds_on_every_completion`, + `test_a_year_that_can_leave_an_unflagged_prior_unsupported_refuses`, + `test_either_bound_of_a_start_year_can_unseat_a_flagged_prior`, + `test_a_quarter_after_the_start_can_exclude_the_pre1956_route`); +- the rule decides an unflagged prior from 1956 on lower credits for every + completion, and the years after a pre-1956 prior's start year on upper + credits + (`test_lower_credits_speak_for_every_completion_of_an_unflagged_prior`, + `test_years_after_a_pre1956_start_count_at_their_upper_credits`); +- no completion of an input error exceeds 4,096 boundary assignments + (`test_a_middle_completion_past_the_boundary_cap_refuses`, + `test_the_boundary_guard_refuses_only_past_4096`). + ## Not in scope No real data, population evaluation, baseline claiming hazard, behavioral diff --git a/docs/design/track_b_insured_status_rulespec_issue.md b/docs/design/track_b_insured_status_rulespec_issue.md index ab6a15c96..64d86c42c 100644 --- a/docs/design/track_b_insured_status_rulespec_issue.md +++ b/docs/design/track_b_insured_status_rulespec_issue.md @@ -46,17 +46,18 @@ observed, named convention-filled or unknown provenance. A coverage-end month stops assignment while elapsed-year and recent-work clocks continue. A nonempty foreign-totalization input is explicitly refused until encoded. -Required outputs are annual QC ranges, favorable assigned-quarter witnesses, -fully/currently/disability insurance, required counts and decision windows, -DLI or a DLI range, unknown years, convention identifiers and the -`decided_despite_unknowns` flag. Each unsupported configuration must return a -named refusal retained in the shared evaluator denominator. A declaration that -contradicts itself, such as a period that ends before it starts, fails before -the rule runs. Otherwise an input error means every filling of the declaration -is invalid; where the encoding can't show that, it refuses by name and keeps -the row, so a listed prior that no completion supports refuses before the rule -calls a later period impossible. Output and refusal records must bind the rule -revision and input declaration. +The encoding must output annual QC ranges, favorable assigned-quarter +witnesses, fully/currently/disability insurance, required counts and decision +windows, DLI or a DLI range, unknown years, convention identifiers and the +`decided_despite_unknowns` flag. It must return a named refusal for each +unsupported configuration, and the shared evaluator keeps that refusal in its +denominator. It rejects a declaration that contradicts itself, such as a +period that ends before it starts, before it applies the rule. Otherwise it +raises an input error only where the declaration has no valid filling. Where +it can't show that, it refuses by name and keeps the row. So where some +completion of the unknown years leaves a listed prior unsupported, it refuses +before it calls a later period impossible. It must bind each output and +refusal record to the rule revision and the input declaration. ## Pasteable review_finding diff --git a/src/populace_dynamics/track_b/insured_status.py b/src/populace_dynamics/track_b/insured_status.py index 93f83c63a..6b0a29f86 100644 --- a/src/populace_dynamics/track_b/insured_status.py +++ b/src/populace_dynamics/track_b/insured_status.py @@ -77,8 +77,8 @@ from datetime import date, timedelta from enum import Enum from fractions import Fraction -from itertools import product -from math import prod +from itertools import combinations, product +from math import comb, prod from types import MappingProxyType from populace_dynamics.track_b._insured_status_qc import ( @@ -1975,11 +1975,12 @@ def _refuse_unsupported_priors(person, lower, upper, month, exit_month): credits or facts the record omits (``_prior_basis``), and those could insure the current period as well. So before credits alone call an established current period impossible, or leave its validity to UNKNOWN - earnings, each listed prior's basis is checked, and a prior's named + earnings, the rule checks each listed prior's basis, and a prior's named refusal keeps the row. A fully-route flag supplies fully insured status from a start the record doesn't give, as the possibility check reads it (``_recent_rule_possible``), so a prior the flag can carry shows nothing - missing. + missing. An input error also needs that support on every completion + (``_refuse_undecided_priors``). """ flagged = bool(person.conditions & _FULLY_INSURED_ROUTE_CONDITIONS) for index in range(len(person.prior_disability_periods)): @@ -1995,6 +1996,120 @@ def _refuse_unsupported_priors(person, lower, upper, month, exit_month): raise +def _refuse_undecided_priors(person, lower, upper, month, exit_month): + """Refuse by name where open years decide a listed prior's support. + + ``_refuse_unsupported_priors`` asks for one completion that supports each + listed prior, while a record whose own credits leave a prior unsupported + refuses it by name. So an input error needs each prior's support on every + completion. Every basis of an unflagged prior from 1956 asks for counts + that more credits only help, so lower credits speak for every completion. + More credits by a prior's start can instead unseat a flagged prior, which + needs 404.130(b) to fail there (``_flag_fits``), or an unflagged prior + from July 1952 through 1955 that rests on RS00301.480 B.1, a route that + 20 of 40 in a later quarter through September 1960 can exclude + (RS00301.480 A). The rule checks those on every completion of the years + open by the prior's start (``_completions``). Credits after its start + year move neither its first quarter's tests nor B.1's counts and only add + to a later 20 of 40, so upper credits speak for every completion of those + years. + """ + flagged = bool(person.conditions & _FULLY_INSURED_ROUTE_CONDITIONS) + for index, period in enumerate(person.prior_disability_periods): + if period.special_insured or ( + date(1952, 7, 1) <= period.start < date(1956, 1, 1) + ): + completions = _completions(lower, upper, period.start.year) + else: + completions = (lower,) + for credits in completions: + try: + _prior_basis( + person, credits, credits, index, month, exit_month + ) + except InsuredConfigurationUnsupported: + if not ( + flagged + and _flag_carries_prior( + person, credits, credits, index, month, exit_month + ) + ): + _refuse( + InsuredUnsupportedReason.UNKNOWN_EARNINGS, + "Unknown earnings decide a listed prior's support", + ) + + +def _refuse_boundary_completions(person, lower, upper): + """Refuse by name where a completion could exceed the boundary cap. + + ``_boundary_variants`` refuses more than 4096 assignments of the QCs in + years that hold a listed prior's first or last quarter, and a middle + count can have more assignments than either bound: two QCs in four + quarters have six. Each world counts some of those years with some of + their quarters open, so counting them all with every quarter open + through death bounds every completion's worlds, and an input error needs + that bound within the cap. + """ + periods = tuple( + (_qid(p.start), _qid(p.end)) for p in person.prior_disability_periods + ) + years = {q // 4 for pair in periods for q in pair} & upper.keys() + if all(lower[year] == upper[year] for year in years): + return + death = _qid(person.death_date) if person.death_date else None + assignments = 1 + for year in years: + fixed, low = lower[year] + allowed = _allowed_quarters( + year, through_quarter=year * 4 + 3, death_quarter=death + ) + vacant = len(set(allowed) - set(fixed)) + assignments *= max( + comb(vacant, min(flexible, vacant)) + for flexible in range(low, upper[year][1] + 1) + ) + if assignments > 4096: + _refuse( + InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY, + "A completion may have more than 4096 boundary assignments", + ) + + +def _completions(lower, upper, last): + """Credits for each completion of the years open through ``last``. + + A year before 1978 credits fixed quarters, so each set of its quarters + within the bounds is a completion, and agricultural QCs that a test may + place support a prior wherever every set they can fill does. A later + year's count takes any placement (RS00301.230 B). More than 4096 + completions refuse by name. + """ + years = [y for y in upper if y <= last and lower[y] != upper[y]] + options = [] + for year in years: + fixed, low = lower[year] + high = upper[year][1] + if year >= 1978: + options.append([(fixed, count) for count in range(low, high + 1)]) + continue + free = [q for q in range(year * 4, year * 4 + 4) if q not in fixed] + options.append( + [ + (tuple(sorted((*fixed, *chosen))), 0) + for size in range(low, high + 1) + for chosen in combinations(free, size) + ] + ) + if prod(map(len, options)) > 4096: + _refuse( + InsuredUnsupportedReason.UNKNOWN_EARNINGS, + "More than 4096 completions decide a listed prior's support", + ) + for chosen in product(*options): + yield {**upper, **dict(zip(years, chosen, strict=True))} + + def _flag_carries_prior(person, lower, upper, index, month, exit_month): """Whether a listed prior begins once a flag supplies fully insured status. @@ -3090,7 +3205,9 @@ def insured_status( Disagreement with the literal any-quarter reading retains the named alternate refusal; post-1980 endings can differ under 404.321(c). Establishment is an input error only if no ordinary, observable, or - flagged specialist route could validate any completion of the facts. + flagged specialist route could validate any completion of the facts, + each listed prior holds on every completion, and no completion can + exceed the boundary-assignment cap. Foreign credits preserve an unmodeled route before credit-count proofs; no totalization minimum or eligibility rule is claimed. A conservative minimum-QC proof precedes fully-insured-only flags and boundary @@ -3174,6 +3291,10 @@ def insured_status( _refuse_unsupported_priors( person, lower, upper, month, coverage_end_month ) + _refuse_undecided_priors( + person, lower, upper, month, coverage_end_month + ) + _refuse_boundary_completions(person, lower, upper) except InsuredConfigurationUnsupported: # A deferred row keeps its own reason, as it does once a # possible declaration survives. diff --git a/tests/README-tiers.md b/tests/README-tiers.md index a08e410f4..2e111e4bf 100644 --- a/tests/README-tiers.md +++ b/tests/README-tiers.md @@ -39,9 +39,9 @@ pytest --collect-only -q -m oracle_policyengine | tail -1 | Tier | Tests at HEAD | |---|---:| -| `unit` | 26,324 | +| `unit` | 26,388 | | `artifact` | 4,527 | | `integration_psid` | 1,471 | | `reproduction_legacy` | 520 | | `oracle_policyengine` | 337 | -| **Total** | **33,178** | +| **Total** | **33,243** | diff --git a/tests/data/track_b/insured_status_examples.yaml b/tests/data/track_b/insured_status_examples.yaml index 70bca2a07..94bbbf1f4 100644 --- a/tests/data/track_b/insured_status_examples.yaml +++ b/tests/data/track_b/insured_status_examples.yaml @@ -911,6 +911,7 @@ source_findings: poms_340_possible_unstated_ceiling: source: poms_rs_00301_345 quote: $10,800 in a TY beginning after 1972 and before 1974; - finding: This ceiling could explain the short-taxable-year example in RS00301.340:10800/3=3600, - if printed10900 meant net earnings before the ceiling rather than already-covered - SEI. The capture does not state the cap step; both readings stay explicit. + finding: This ceiling could explain the short-taxable-year example in RS 00301.340, + where $10,800/3 gives $3,600, if the printed $10,900 meant net earnings before + the ceiling rather than already-covered SEI. The capture does not state the cap + step; both readings stay explicit. diff --git a/tests/test_track_b_insured_status_fix_round_24.py b/tests/test_track_b_insured_status_fix_round_24.py new file mode 100644 index 000000000..cb779772c --- /dev/null +++ b/tests/test_track_b_insured_status_fix_round_24.py @@ -0,0 +1,559 @@ +"""Round 24: an input error holds on every completion of the record. + +Verification class: statutory conformance on invented declarations; no +population, behavioral or forecast claim. + +``InvalidFamilyInput`` drops a row, so an established current period with no +possible insured quarter raises it only where every completion of the +record's UNKNOWN years would. Each listed prior then needs support on every +completion, not just one: where a year open by a prior's start can leave it +unsupported, the record refuses by name. Before 1978 a year credits fixed +quarters, so each set of its quarters makes a completion, and a 1953 quarter +after a pre-1956 prior's start can exclude RS 00301.480 B.1's route where a +count the rule places to suit each test can't. A middle count can have more +boundary assignments than either bound, so the record also refuses where +some completion could exceed the 4,096 cap. +""" + +import random +from dataclasses import replace +from datetime import date, timedelta +from itertools import product + +import pytest +from hypothesis import given, settings +from hypothesis import strategies as st + +from populace_dynamics.track_b import insured_status as i +from tests.test_track_b_insured_status import history +from tests.test_track_b_insured_status_fix_round_23 import ( + ALL, + DISABILITY, + FEMALE, + MALE, + OBSERVED, + UNKNOWN, + UNSUPPORTED_PRIOR, + Reason, + _person, + _refused, + _row, +) + +NO_POSSIBLE = "no possible insured disabled quarter" +UNDECIDED = "Unknown earnings decide a listed prior's support" +BOUNDARY_CAP = "More than 4096 boundary assignments" +BOUNDARY_GUARD = "A completion may have more than 4096 boundary assignments" +COMPLETION_CAP = "More than 4096 completions decide a listed prior's support" +PROPERTY = settings(max_examples=25, deadline=None, derandomize=True) +MONTH = date(2006, 1, 1) + + +def _year(year, fill): + """An UNKNOWN row, a count from 1978, or quarter flags before.""" + if fill is None: + return i.CoverageYear(UNKNOWN) + if year < 1978: + return i.CoverageYear(OBSERVED, qc_quarters=fill) + return i.CoverageYear(OBSERVED, qc_count=fill) + + +def _invalid(person, years, month, **options): + with pytest.raises(i.InvalidFamilyInput, match=NO_POSSIBLE): + _row(person, years, month, **options) + + +def _expect(outcome, person, years, month, **options): + """Check an input error, or a refusal's reason and detail.""" + if outcome is None: + _invalid(person, years, month, **options) + return + reason, detail = outcome + assert _refused(reason, person, years, month, **options) == detail + + +UNSUPPORTED = (Reason.ASSIGNMENT_COMPLEXITY, UNSUPPORTED_PRIOR) +OPEN = (Reason.UNKNOWN_EARNINGS, UNDECIDED) + + +# A year open by a listed prior's start that can leave it unsupported. + + +def _unflagged(fill, counts): + person = _person( + date(1950, 2, 2), + i.DisabilityPeriod(date(1990, 1, 1), date(1991, 12, 31)), + onset=date(2005, 1, 15), + established=True, + ) + years = history(person, MONTH, counts) + years[1989] = _year(1989, fill) + return person, years + + +SIXTEEN = {year: 4 for year in range(1981, 1985)} + + +@pytest.mark.parametrize( + "fill,outcome", + ( + (None, OPEN), + (0, UNSUPPORTED), + (1, UNSUPPORTED), + (2, None), + (3, None), + (4, None), + ), +) +def test_a_year_that_can_leave_an_unflagged_prior_unsupported_refuses( + fill, outcome +): + # Plain arithmetic: born 1950-02-02, she needs 18 QCs to be fully insured + # at 1990Q1, and 1981 to 1984 give 16. 404.130(b) counts those 16 in the + # 40 quarters ending 1990Q1, and four 1989 QCs bring it to 20; past + # blindness asks only the 18. So two or more 1989 QCs support the prior, + # and none or one leaves it unsupported. No QC follows 1989, so no + # completion insures the 2005 period. + _expect(outcome, *_unflagged(fill, SIXTEEN), MONTH) + + +def _flagged(fill, counts): + person = _person( + date(1965, 6, 15), + i.DisabilityPeriod( + date(1990, 4, 1), date(1990, 12, 31), special_insured=True + ), + onset=date(2005, 1, 15), + established=True, + ) + years = history(person, MONTH, counts) + years[1990] = _year(1990, fill) + return person, years + + +EIGHTEEN = {1983: 4, 1984: 4, 1985: 2, 1987: 4, 1988: 4} +ROUTE_SHORT = {**EIGHTEEN, 1987: 3} + + +@pytest.mark.parametrize( + "counts,fill,outcome", + ( + (EIGHTEEN, None, OPEN), + (EIGHTEEN, 0, None), + (EIGHTEEN, 3, None), + (EIGHTEEN, 4, UNSUPPORTED), + (ROUTE_SHORT, None, OPEN), + (ROUTE_SHORT, 0, UNSUPPORTED), + (ROUTE_SHORT, 1, None), + (ROUTE_SHORT, 4, None), + ), +) +def test_either_bound_of_a_start_year_can_unseat_a_flagged_prior( + counts, fill, outcome +): + # Plain arithmetic: born 1965-06-15, she attains 21 in 1986Q2, so + # 404.130(c) at 1990Q2 counts the 16 quarters from 1986Q3 and asks + # eight. 404.130(b) counts the 40 quarters ending 1990Q2. With 1987 and + # 1988's eight, 404.130(c) holds, and 1983 to 1988 give 404.130(b) 18: + # four 1990 QCs fill 1990Q1 and 1990Q2 and bring it to 20, so no + # placement fits the flag, while three or fewer can leave one or none + # there. With three in 1987, 404.130(b) can't reach 20, and 404.130(c) + # needs a 1990 QC in 1990Q1 or 1990Q2. + _expect(outcome, *_flagged(fill, counts), MONTH) + + +@pytest.mark.parametrize("fill", (None, 0, 1, 2, 3, 4)) +@pytest.mark.parametrize( + "record,counts", + ( + pytest.param(_unflagged, {**SIXTEEN, 1985: 4}, id="unflagged"), + pytest.param(_flagged, {**EIGHTEEN, 1983: 3}, id="flagged"), + ), +) +def test_a_prior_every_completion_supports_keeps_the_input_error( + record, counts, fill +): + # Plain arithmetic: four 1985 QCs give the unflagged prior 20 of the 40 + # quarters ending 1990Q1, and 20 QCs, whatever 1989 holds. Three 1983 + # QCs hold the flagged prior's 404.130(b) count at 19 or fewer whatever + # 1990 holds, and 1987 and 1988 keep 404.130(c)'s eight. + _invalid(*record(fill, counts), MONTH) + + +@pytest.mark.parametrize("fill", (None, 0, 1, 4)) +def test_a_flag_that_carries_the_prior_keeps_the_input_error(fill): + # Plain arithmetic: a deemed fully insured status supplies the 18 QCs + # past blindness asks for, so the flag carries the prior on every + # completion of 1989, and still no completion insures the 2005 period. + person, years = _unflagged(fill, SIXTEEN) + deemed = replace( + person, + conditions=frozenset({i.CoverageCondition.DEEMED_FULLY_INSURED}), + ) + _invalid(deemed, years, MONTH) + + +# A 1953 quarter after a pre-1956 prior's start. + + +PRE1956_PRIOR = i.DisabilityPeriod(date(1953, 1, 1), date(1953, 3, 31)) + + +def _pre1956(flags, open_years=(), prior=PRE1956_PRIOR): + person = _person( + date(1915, 3, 2), + prior, + onset=date(1965, 6, 15), + established=True, + ) + month = date(1966, 1, 1) + years = history(person, month) + for year, quarters in { + 1942: (True, False, False, False), + 1943: (False, False, True, True), + 1944: (True,) * 4, + 1945: (True,) * 4, + 1946: (True, False, False, False), + 1951: (True,) * 4, + 1952: (True,) * 4, + }.items(): + years[year] = _year(year, quarters) + years[1953] = _year(1953, flags) + for year in open_years: + years[year] = _year(year, None) + return person, years, month + + +@pytest.mark.parametrize("flags", (None, *product((False, True), repeat=4))) +def test_a_quarter_after_the_start_can_exclude_the_pre1956_route(flags): + # Plain arithmetic: she has 20 QCs before 1953 and one in every quarter + # of 1951 and 1952, so RS 00301.480 B.1's counts hold at her prior's + # start in 1953Q1. The 40 quarters ending 1953Q1 hold 19, so a 1953Q1 QC + # meets 404.130(b) there. Without one, a 1953Q2 QC brings the 40 + # quarters ending 1953Q2 to 20, a quarter after the one the prior + # covers, so only the any-quarter reading of RS 00301.480 A excludes + # B.1's route, and that completion refuses by the route's name. No other + # quarter reaches 20, and a count the rule places to suit each test would + # put its QC in 1953Q1 and hide that completion. + if flags is None: + outcome = OPEN + elif flags[1] and not flags[0]: + outcome = ( + Reason.DISABILITY_BEFORE_1956, + "RS00301.480 may have begun a listed prior before 1956", + ) + else: + outcome = None + _expect(outcome, *_pre1956(flags)) + + +def test_more_completions_than_the_cap_refuse_by_their_number(): + # Plain arithmetic: four UNKNOWN years from 1947 through 1950 give 16 + # quarter sets each and 65,536 completions in all, past the cap. Their + # upper bound gives 404.130(b) 35 of the 40 quarters ending 1953Q1, so + # some completion supports the prior. + person, years, month = _pre1956((False,) * 4, range(1947, 1951)) + assert _refused(Reason.UNKNOWN_EARNINGS, person, years, month) == ( + COMPLETION_CAP + ) + + +def test_years_after_a_pre1956_start_count_at_their_upper_credits(): + # Plain arithmetic: a 1953Q1 QC brings the 40 quarters ending 1953Q1 to + # 20, so 404.130(b) supports the prior on every completion. QCs from + # 1956 to 1959 can only add to a later 20 of 40, so their upper credits + # speak for their 65,536 completions, and the rule lists none of them. + _invalid(*_pre1956((True, False, False, False), range(1956, 1960))) + + +def test_a_prior_before_july_1952_rests_on_lower_credits(): + # Plain arithmetic: RS 00301.480 B.1 begins no period before July 1952, + # so a prior from January 1952 rests on 404.130(b), which more credits + # only help. The 40 quarters ending 1952Q1 hold 16 on lower credits, so + # the rule refuses on those without listing the 65,536 completions of + # 1947 to 1950. + prior = i.DisabilityPeriod(date(1952, 1, 1), date(1952, 3, 31)) + person, years, month = _pre1956((False,) * 4, range(1947, 1951), prior) + assert _refused(Reason.UNKNOWN_EARNINGS, person, years, month) == ( + UNDECIDED + ) + + +# A middle completion past the boundary cap. + +BOUNDARY_PRIORS = tuple( + i.DisabilityPeriod(date(year, 10, 1), date(year + 1, 3, 31)) + for year in (1980, 1984, 1988) +) +ENDPOINT_YEARS = (1980, 1981, 1984, 1985, 1988, 1989) +FOUR_ENDPOINTS = {1980: 2, 1981: 2, 1984: 2, 1985: 2} + + +def _boundary(counts, fills): + person = _person( + date(1955, 2, 2), + *BOUNDARY_PRIORS, + onset=date(2005, 6, 15), + established=True, + ) + years = history(person, MONTH, {1977: 4, 1978: 4, 1979: 4, **counts}) + for year, fill in fills.items(): + years[year] = _year(year, fill) + return person, years + + +def test_a_middle_completion_past_the_boundary_cap_refuses(): + # Plain arithmetic: each prior runs from a fourth quarter to the next + # first quarter, so each of its two years keeps four quarters open, and + # two QCs there have six assignments. Four such years give 1,296, and two + # QCs in each of 1988 and 1989 make 46,656, past the cap, though none or + # four in each leave one assignment there. Past blindness supports each + # prior on the 12 QCs from 1977 to 1979, and no QC follows 1989. + person, years = _boundary(FOUR_ENDPOINTS, {1988: None, 1989: None}) + assert ( + _refused(Reason.ASSIGNMENT_COMPLEXITY, person, years, MONTH) + == BOUNDARY_GUARD + ) + person, years = _boundary(FOUR_ENDPOINTS, {1988: 2, 1989: 2}) + assert ( + _refused(Reason.ASSIGNMENT_COMPLEXITY, person, years, MONTH) + == BOUNDARY_CAP + ) + for fills in product((0, 4), repeat=2): + fills = dict(zip((1988, 1989), fills, strict=True)) + _invalid(*_boundary(FOUR_ENDPOINTS, fills), MONTH) + + +def test_endpoint_years_within_the_cap_keep_the_input_error(): + # Plain arithmetic: two endpoint years with two QCs give 36, and the two + # open years can multiply that by at most 36, to 1,296. + counts = {1980: 2, 1981: 2} + _invalid(*_boundary(counts, {1988: None, 1989: None}), MONTH) + for fills in product(range(5), repeat=2): + fills = dict(zip((1988, 1989), fills, strict=True)) + _invalid(*_boundary(counts, fills), MONTH) + + +def _one_each(changes=None): + """One QC in each endpoint year, with its four assignments.""" + credits = dict.fromkeys(ENDPOINT_YEARS, ((), 1)) + credits.update(changes or {}) + return credits + + +def test_the_boundary_guard_refuses_only_past_4096(): + # Plain arithmetic: one QC in four open quarters has four assignments, so + # six endpoint years give exactly 4,096, which the cap allows. A 1989 + # that can hold two has six, and 6,144 exceeds the cap. + person = _person(date(1955, 2, 2), *BOUNDARY_PRIORS) + lower = _one_each({1989: ((), 0)}) + i._refuse_boundary_completions(person, lower, _one_each()) + with pytest.raises( + i.InsuredConfigurationUnsupported, match=BOUNDARY_GUARD + ): + i._refuse_boundary_completions( + person, lower, _one_each({1989: ((), 2)}) + ) + + +def test_known_endpoint_years_leave_the_cap_to_the_record(): + # Plain arithmetic: two QCs in each of six endpoint years have 46,656 + # assignments, but with no year open every world is the record's own, + # and ``_boundary_variants`` counts its assignments. + person = _person(date(1955, 2, 2), *BOUNDARY_PRIORS) + known = dict.fromkeys(ENDPOINT_YEARS, ((), 2)) + i._refuse_boundary_completions(person, known, known) + + +def test_the_boundary_guard_leaves_fixed_quarters_out(): + # Plain arithmetic: a deferred year before 1978 with two fixed quarters + # can add none, one or both of the other two, so it has at most two + # assignments, and six such endpoint years give 64. Counting all four + # quarters as open would give six each and 46,656. + priors = tuple( + i.DisabilityPeriod(date(year, 10, 1), date(year + 1, 3, 31)) + for year in (1960, 1964, 1968) + ) + person = _person(date(1935, 2, 2), *priors) + endpoints = (1960, 1961, 1964, 1965, 1968, 1969) + lower = {year: ((year * 4, year * 4 + 1), 0) for year in endpoints} + upper = {year: ((year * 4, year * 4 + 1), 2) for year in endpoints} + i._refuse_boundary_completions(person, lower, upper) + + +def test_the_boundary_guard_counts_no_quarter_after_death(): + # Plain arithmetic: a death in 1989Q2 leaves 1989 two quarters, where one + # QC has two assignments and two have one, so 1,024 times two stays + # within the cap. + person = _person( + date(1955, 2, 2), *BOUNDARY_PRIORS, death_date=date(1989, 5, 10) + ) + lower = _one_each({1989: ((), 0)}) + i._refuse_boundary_completions(person, lower, _one_each({1989: ((), 2)})) + + +# The completions of open years. + + +def test_completions_list_quarter_sets_before_1978_and_counts_after(): + lower = {1977: ((), 0), 1978: ((), 0), 1979: ((), 2)} + upper = {1977: ((), 4), 1978: ((), 4), 1979: ((), 2)} + found = list(i._completions(lower, upper, 1979)) + assert len(found) == 16 * 5 + assert {c[1977] for c in found} == { + (tuple(1977 * 4 + q for q in range(4) if flags[q]), 0) + for flags in product((False, True), repeat=4) + } + assert {c[1978] for c in found} == {((), n) for n in range(5)} + assert all(c[1979] == ((), 2) for c in found) + # Years after ``last`` keep their upper credits. + later = {c[1978] for c in i._completions(lower, upper, 1977)} + assert later == {((), 4)} + + +def test_completions_keep_a_deferred_year_s_fixed_quarters(): + # A deferred year before 1978 credits its fixed quarters on every + # completion and may add any of the other three. + fixed = (1960 * 4 + 1,) + found = list(i._completions({1960: (fixed, 0)}, {1960: (fixed, 3)}, 1960)) + assert len(found) == 8 + assert all(set(fixed) <= set(c[1960][0]) for c in found) + + +@pytest.mark.parametrize( + "first,years,refused", + ((1978, 5, False), (1978, 6, True), (1960, 3, False), (1960, 4, True)), +) +def test_completions_refuse_past_4096(first, years, refused): + # Plain arithmetic: five counts a year give 3,125 for five years and + # 15,625 for six; 16 quarter sets a year give 4,096 for three years and + # 65,536 for four. + span = range(first, first + years) + lower = dict.fromkeys(span, ((), 0)) + upper = dict.fromkeys(span, ((), 4)) + completions = i._completions(lower, upper, first + years) + if refused: + with pytest.raises( + i.InsuredConfigurationUnsupported, match=COMPLETION_CAP + ): + next(completions) + else: + assert next(completions).keys() == upper.keys() + + +# Properties on invented records. + + +def _draw(rng): + """Listed priors before an established current period, with open years.""" + early = rng.random() < 0.25 + if early: + birth = date(rng.randint(1900, 1925), rng.randint(1, 12), 2) + start = max( + date(rng.randint(1952, 1955), rng.choice((1, 4, 7, 10)), 1), + date(1952, 7, 1), + ) + else: + birth = date(rng.randint(1925, 1972), rng.randint(1, 12), 2) + start = date( + birth.year + rng.randint(22, 44), rng.choice((1, 4, 7, 10)), 1 + ) + priors = [] + for _ in range(1 if rng.random() < 0.7 else 2): + end = start + timedelta(days=rng.randint(60, 900)) + young = start < date(birth.year + 31, birth.month, birth.day) + flagged = young and not early and rng.random() < 0.5 + priors.append(i.DisabilityPeriod(start, end, special_insured=flagged)) + later = end + timedelta(days=rng.randint(200, 2000)) + start = date(later.year, rng.choice((1, 4, 7, 10)), 1) + onset = date( + priors[-1].end.year + rng.randint(6, 14), rng.randint(1, 12), 15 + ) + month = date(onset.year + 1, 1, 1) + person = _person( + birth, + *priors, + onset=onset, + established=True, + sex=rng.choice((FEMALE, MALE)), + ) + years = history(person, month) + first = max(1937, birth.year + 16) + density = rng.choice((0.3, 0.6, 0.85)) + for year in range(first, min(priors[-1].end.year + 1, month.year) + 1): + if rng.random() < density: + if year < 1978: + fill = tuple(rng.random() < 0.75 for _ in range(4)) + else: + fill = rng.randint(1, 4) + years[year] = _year(year, fill) + span = range(first, priors[-1].start.year + 1) + unknown = sorted(rng.sample(span, rng.choice((1, 1, 2)))) + if unknown[0] < 1978: + unknown = unknown[:1] + for year in unknown: + years[year] = _year(year, None) + return person, years, month, unknown, rng.choice((ALL, DISABILITY)) + + +def _record(seed): + """The first record the seed's draws give that a Person accepts.""" + rng = random.Random(seed) + while True: + try: + return _draw(rng) + except i.InvalidFamilyInput: + continue + + +def _fills(year): + if year < 1978: + return list(product((False, True), repeat=4)) + return list(range(5)) + + +def _input_error(person, years, month, test): + try: + _row(person, years, month, test=test) + except i.InvalidFamilyInput: + return True + return False + + +@PROPERTY +@given(seed=st.integers(0, 2**32 - 1)) +def test_an_input_error_holds_on_every_completion(seed): + person, years, month, unknown, test = _record(seed) + if not _input_error(person, years, month, test): + return + for fills in product(*map(_fills, unknown)): + filled = dict(years) + for year, fill in zip(unknown, fills, strict=True): + filled[year] = _year(year, fill) + assert _input_error(person, filled, month, test), (unknown, fills) + + +def _supported(person, credits, index, month): + try: + i._prior_basis(person, credits, credits, index, month, None) + except i.InsuredConfigurationUnsupported: + return False + return True + + +@PROPERTY +@given(seed=st.integers(0, 2**32 - 1)) +def test_lower_credits_speak_for_every_completion_of_an_unflagged_prior(seed): + # ``_refuse_undecided_priors`` reads an unflagged prior from 1956 on + # lower credits alone; a search of every completion agrees. + person, years, month, _, _ = _record(seed) + lower = {y: i._credits(y, row, False) for y, row in years.items()} + upper = {y: i._credits(y, row, True) for y, row in years.items()} + for index, period in enumerate(person.prior_disability_periods): + if period.special_insured or period.start < date(1956, 1, 1): + continue + every = all( + _supported(person, credits, index, month) + for credits in i._completions(lower, upper, period.start.year) + ) + assert _supported(person, lower, index, month) is every diff --git a/tests/tier_counts.json b/tests/tier_counts.json index 1776a00b5..35326a806 100644 --- a/tests/tier_counts.json +++ b/tests/tier_counts.json @@ -1,7 +1,7 @@ { "schema_version": 1, "counts": { - "unit": 26324, + "unit": 26388, "artifact": 4527, "integration_psid": 1471, "reproduction_legacy": 520, From d30e44267cd25cbf804f8b4e9a07679f2c4a9939 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Tue, 3 Nov 2026 19:12:58 -0500 Subject: [PATCH 45/46] Record round 23's 107 cloud mutation kills (#562) Cloud brief 6870 ran round 23's 107 mutations at f32d8812 through every insured status module (PR #562 comment 6618201683). All 107 failed a named test, and every run's open audit counted no restricted open. The ledger takes the records, the runner, the test hashes and the replay steps. The design note gets one sentence for the run and two for the stress oracle, whose full-scan test fails on both mutations of its scan. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 8 + .../track_b_insured_status_mutations.json | 2389 ++++++++++++++++- 2 files changed, 2396 insertions(+), 1 deletion(-) diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index 2f92af8aa..82566d983 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -2164,6 +2164,10 @@ through the query. The test draws records from the base, entitlement-month, under-31 and subsequent-special generators. On two credit placements of each, it compares the scans with and without the declared periods, with and without the subsequent-special route, and under both readings. +A cloud session ran the test on two mutations of the scan at `f32d8812`, and +both failed it (PR #562 comment 6618201683). `upward_first` scans up from +the first credit and returns the earliest quarter that insures an onset, and +`skip_query` starts one quarter below the query. ## Round 16 diagnostics on the reported start @@ -3666,6 +3670,10 @@ blindness begin a prior before 1973, `blind_basis_1972` lets it begin one in 404.130(c)'s 12-quarter floor or round its half up. Each of the 37 fails round 23's module. +A cloud session then ran all 107 at `f32d8812`, through every insured status +module. All 107 failed a named test, with no restricted open +(`round_23_mutations`, PR #562 comment 6618201683). + Six local mutations of the note check each fail its read guard before the check opens a file outside this note and the insured status modules: a recursive `rglob`, a `**` glob, a subfolder glob, and a flat glob, a byte read and an diff --git a/docs/design/track_b_insured_status_mutations.json b/docs/design/track_b_insured_status_mutations.json index e234286e7..94bbe9f54 100644 --- a/docs/design/track_b_insured_status_mutations.json +++ b/docs/design/track_b_insured_status_mutations.json @@ -11313,5 +11313,2392 @@ "tests/test_track_b_insured_status_fix_round_2.py": "c1d00971949eb7d1f9ac458dfea1b5e47922fb3d0047a50a764e7400f9321835" }, "round_22_replay": "Write round_22_runner_source to scratch/review/run_round22_named.py. For each round_22_mutations record, write name/source_sha256/changes to its spec_path, then execute its exact command at 7b5b126a. Mutations apply only in memory.", - "round_22_final_source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880" + "round_22_final_source_sha256": "875b3a73c3cfa76340a514ab5681b79379f7f2b23698a7cbd0e62f0b6d362880", + "round_23_mutations": [ + { + "changes": [ + { + "after": " chosen = vacant[:count]\n", + "before": " chosen = vacant[-count:] if year == at.year else vacant[:count]\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-worst_always_early.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/worst_always_early /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_prior_basis_split_widens_the_qualifying_quarters" + ], + "log": "scratch/review/round23-mutation-worst_always_early.log", + "name": "worst_always_early", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-worst_always_early.json" + }, + { + "changes": [ + { + "after": " chosen = vacant[-count:]\n", + "before": " chosen = vacant[-count:] if year == at.year else vacant[:count]\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-worst_always_late.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/worst_always_late /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_placement_or_year_that_decides_the_basis_refuses" + ], + "log": "scratch/review/round23-mutation-worst_always_late.log", + "name": "worst_always_late", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-worst_always_late.json" + }, + { + "changes": [ + { + "after": " if _witness(\n person,\n lower,\n person.disability_onset,\n coverage_end_month,\n InsuredTest.DISABILITY,\n )[0]:\n lo_start = hi_start = person.disability_onset\n", + "before": " if _start_fixed(\n person,\n lower,\n person.disability_onset,\n month,\n coverage_end_month,\n ):\n lo_start = hi_start = person.disability_onset\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-start_on_favorable_placement.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/start_on_favorable_placement /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_status_on_every_placement_computes" + ], + "log": "scratch/review/round23-mutation-start_on_favorable_placement.log", + "name": "start_on_favorable_placement", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-start_on_favorable_placement.json" + }, + { + "changes": [ + { + "after": "", + "before": " if prior_unknown or current_unknown:\n _settle_every_history(\n person, lower, month, coverage_end_month, decisions, dli\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-no_universal_proof.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/no_universal_proof /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_date[known_end]" + ], + "log": "scratch/review/round23-mutation-no_universal_proof.log", + "name": "no_universal_proof", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-no_universal_proof.json" + }, + { + "changes": [ + { + "after": " if prior_unknown:\n _settle_every_history(", + "before": " if prior_unknown or current_unknown:\n _settle_every_history(" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-proof_skips_open_period.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/proof_skips_open_period /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_unknown_establishment_alone_refuses[InsuredTest.ALL]" + ], + "log": "scratch/review/round23-mutation-proof_skips_open_period.log", + "name": "proof_skips_open_period", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-proof_skips_open_period.json" + }, + { + "changes": [ + { + "after": " if current_unknown:\n _settle_every_history(", + "before": " if prior_unknown or current_unknown:\n _settle_every_history(" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-proof_skips_unknown_priors.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/proof_skips_unknown_priors /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_date[known_end]" + ], + "log": "scratch/review/round23-mutation-proof_skips_unknown_priors.log", + "name": "proof_skips_unknown_priors", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-proof_skips_unknown_priors.json" + }, + { + "changes": [ + { + "after": " _settle_every_history(\n person, upper, month,", + "before": " _settle_every_history(\n person, lower, month," + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-proof_on_upper_credits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/proof_on_upper_credits /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_date[unknown_year]" + ], + "log": "scratch/review/round23-mutation-proof_on_upper_credits.log", + "name": "proof_on_upper_credits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-proof_on_upper_credits.json" + }, + { + "changes": [ + { + "after": " if (\n decision is not None\n and False\n and not _every_placement_passes(\n", + "before": " if (\n decision is not None\n and decision.insured\n and not _every_placement_passes(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-proof_skips_statuses.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/proof_skips_statuses /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_status[first_day-InsuredTest.ALL]" + ], + "log": "scratch/review/round23-mutation-proof_skips_statuses.log", + "name": "proof_skips_statuses", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-proof_skips_statuses.json" + }, + { + "changes": [ + { + "after": " if (\n dli is not None\n and False\n and not _every_placement_passes(\n", + "before": " if (\n dli is not None\n and dli.lower is not None\n and not _every_placement_passes(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-proof_skips_the_date.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/proof_skips_the_date /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_date[known_end]" + ], + "log": "scratch/review/round23-mutation-proof_skips_the_date.log", + "name": "proof_skips_the_date", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-proof_skips_the_date.json" + }, + { + "changes": [ + { + "after": " month,\n", + "before": " decision.qualifying_quarter,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-status_tested_at_query.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/status_tested_at_query /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_status_stands_at_the_quarter_it_reports" + ], + "log": "scratch/review/round23-mutation-status_tested_at_query.log", + "name": "status_tested_at_query", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-status_tested_at_query.json" + }, + { + "changes": [ + { + "after": " month,\n", + "before": " _qdate(_qid(dli.lower)),\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-date_tested_at_query.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/date_tested_at_query /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_2.py::test_unknown_period_status_and_dli_bounds_contain_concrete_fillings" + ], + "log": "scratch/review/round23-mutation-date_tested_at_query.log", + "name": "date_tested_at_query", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-date_tested_at_query.json" + }, + { + "changes": [ + { + "after": " bare = person\n for kind, decision", + "before": " bare = replace(person, prior_disability_periods=())\n for kind, decision" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-proof_keeps_listed_priors.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/proof_keeps_listed_priors /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_unknown_establishment_needs_the_disregard" + ], + "log": "scratch/review/round23-mutation-proof_keeps_listed_priors.log", + "name": "proof_keeps_listed_priors", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-proof_keeps_listed_priors.json" + }, + { + "changes": [ + { + "after": " if False\n", + "before": " if blind is not None\n and not current_unknown\n and _prior_start_binds(\n person, lower, upper, index, month, coverage_end_month, blind\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-no_listed_prior_check.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/no_listed_prior_check /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_prior_basis_split_widens_the_qualifying_quarters" + ], + "log": "scratch/review/round23-mutation-no_listed_prior_check.log", + "name": "no_listed_prior_check", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-no_listed_prior_check.json" + }, + { + "changes": [ + { + "after": " if blind is not None\n and _prior_start_binds(\n person, lower, upper, index, month, coverage_end_month, blind\n )\n", + "before": " if blind is not None\n and not current_unknown\n and _prior_start_binds(\n person, lower, upper, index, month, coverage_end_month, blind\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-binding_reaches_open_period.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/binding_reaches_open_period /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_an_unknown_year_leaves_a_proven_result_to_the_proof" + ], + "log": "scratch/review/round23-mutation-binding_reaches_open_period.log", + "name": "binding_reaches_open_period", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-binding_reaches_open_period.json" + }, + { + "changes": [ + { + "after": " if False:\n", + "before": " if binding and unknown:\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-unknown_year_searches.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/unknown_year_searches /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_an_unknown_year_refuses" + ], + "log": "scratch/review/round23-mutation-unknown_year_searches.log", + "name": "unknown_year_searches", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-unknown_year_searches.json" + }, + { + "changes": [ + { + "after": " True\n or not (\n", + "before": " _prior_passes(\n person, filling, index, exit_month, blind=blind, **options\n )\n and not (\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-keeps_every_filling.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/keeps_every_filling /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_prior_basis_split_widens_the_qualifying_quarters" + ], + "log": "scratch/review/round23-mutation-keeps_every_filling.log", + "name": "keeps_every_filling", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-keeps_every_filling.json" + }, + { + "changes": [ + { + "after": "", + "before": " and not (\n person.prior_disability_periods[index].special_insured\n and _prior_passes(\n person,\n filling,\n index,\n exit_month,\n blind=False,\n ordinary_only=True,\n **options,\n )\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-keeps_ignores_the_flag.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/keeps_ignores_the_flag /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_flagged_prior_needs_paragraph_c_without_paragraph_b" + ], + "log": "scratch/review/round23-mutation-keeps_ignores_the_flag.log", + "name": "keeps_ignores_the_flag", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-keeps_ignores_the_flag.json" + }, + { + "changes": [ + { + "after": "", + "before": " if not _keeps_priors(person, filling, binding, exit_month):\n continue\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-start_search_ignores_priors.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/start_search_ignores_priors /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_split_start_names_the_listed_prior" + ], + "log": "scratch/review/round23-mutation-start_search_ignores_priors.log", + "name": "start_search_ignores_priors", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-start_search_ignores_priors.json" + }, + { + "changes": [ + { + "after": "", + "before": " if _keeps_priors(person, filling, binding, exit_month)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-listed_search_ignores_priors.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/listed_search_ignores_priors /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_prior_basis_split_widens_the_qualifying_quarters" + ], + "log": "scratch/review/round23-mutation-listed_search_ignores_priors.log", + "name": "listed_search_ignores_priors", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-listed_search_ignores_priors.json" + }, + { + "changes": [ + { + "after": " year\n for index, _ in ()\n", + "before": " year\n for index, _ in binding\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-no_prior_years.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/no_prior_years /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_prior_basis_split_widens_the_qualifying_quarters" + ], + "log": "scratch/review/round23-mutation-no_prior_years.log", + "name": "no_prior_years", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-no_prior_years.json" + }, + { + "changes": [ + { + "after": " )\n", + "before": " ) | _prior_sensitive_years(person, binding)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-start_search_skips_prior_years.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/start_search_skips_prior_years /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_reaches_a_year_the_start_cannot" + ], + "log": "scratch/review/round23-mutation-start_search_skips_prior_years.log", + "name": "start_search_skips_prior_years", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-start_search_skips_prior_years.json" + }, + { + "changes": [ + { + "after": " return settle(())\n", + "before": " return settle(binding)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-first_search_drops_binding.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/first_search_drops_binding /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_split_start_names_the_listed_prior" + ], + "log": "scratch/review/round23-mutation-first_search_drops_binding.log", + "name": "first_search_drops_binding", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-first_search_drops_binding.json" + }, + { + "changes": [ + { + "after": " for filling, completed in _fillings_keeping_start(\n person, credits, start, month, exit_month, favored, ()\n", + "before": " for filling, completed in _fillings_keeping_start(\n person, credits, start, month, exit_month, favored, binding\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-date_search_drops_binding.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/date_search_drops_binding /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_listed_prior_holds_every_ending_to_the_date" + ], + "log": "scratch/review/round23-mutation-date_search_drops_binding.log", + "name": "date_search_drops_binding", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-date_search_drops_binding.json" + }, + { + "changes": [ + { + "after": "", + "before": " *((InsuredTest.DISABILITY,) if binding else ()),\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-disability_left_out_of_search.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/disability_left_out_of_search /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_prior_basis_split_widens_the_qualifying_quarters" + ], + "log": "scratch/review/round23-mutation-disability_left_out_of_search.log", + "name": "disability_left_out_of_search", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-disability_left_out_of_search.json" + }, + { + "changes": [ + { + "after": " option,\n", + "before": " person if kind is InsuredTest.DISABILITY else option,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-disability_reads_the_completion.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/disability_reads_the_completion /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_period_begun_in_the_age_31_quarter_rests_on_paragraph_d" + ], + "log": "scratch/review/round23-mutation-disability_reads_the_completion.log", + "name": "disability_reads_the_completion", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-disability_reads_the_completion.json" + }, + { + "changes": [ + { + "after": " dated=False,\n last_insured=last_insured,\n reported=reported,\n detail=\"Annual placement decides", + "before": " dated=dated,\n last_insured=last_insured,\n reported=reported,\n detail=\"Annual placement decides" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-listed_search_skips_the_date.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/listed_search_skips_the_date /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_periods_still_may_not_share_a_day" + ], + "log": "scratch/review/round23-mutation-listed_search_skips_the_date.log", + "name": "listed_search_skips_the_date", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-listed_search_skips_the_date.json" + }, + { + "changes": [ + { + "after": " if not person.prior_disability_periods[index].special_insured:\n return True\n", + "before": " if not person.prior_disability_periods[index].special_insured:\n return not every\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-unflagged_refuses_every_placement.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/unflagged_refuses_every_placement /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_an_open_flag_keeps_paragraph_b_where_every_placement_meets_it" + ], + "log": "scratch/review/round23-mutation-unflagged_refuses_every_placement.log", + "name": "unflagged_refuses_every_placement", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-unflagged_refuses_every_placement.json" + }, + { + "changes": [ + { + "after": " True\n and not _every_placement_begins(\n", + "before": " _prior_passes(\n person, upper, index, exit_month, blind=False, **options\n )\n and not _every_placement_begins(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-flagged_ignores_support.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/flagged_ignores_support /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_only_a_middle_completion_fits_a_flag[0-InsuredTest.ALL-InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY-No" + ], + "log": "scratch/review/round23-mutation-flagged_ignores_support.log", + "name": "flagged_ignores_support", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-flagged_ignores_support.json" + }, + { + "changes": [ + { + "after": "", + "before": " and not _every_placement_begins(\n person,\n lower,\n index,\n month,\n exit_month,\n blind=False,\n ordinary_only=True,\n **options,\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-flagged_ignores_ordinary_rule.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/flagged_ignores_ordinary_rule /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_flag_every_completion_contradicts_refuses_by_that_name[6]" + ], + "log": "scratch/review/round23-mutation-flagged_ignores_ordinary_rule.log", + "name": "flagged_ignores_ordinary_rule", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-flagged_ignores_ordinary_rule.json" + }, + { + "changes": [ + { + "after": " return True\n", + "before": " return not every or _prior_passes(\n person, upper, index, exit_month, blind=False, ordinary_only=True\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-flagged_refuses_every_placement.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/flagged_refuses_every_placement /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_an_ended_current_period_counts_as_the_prior_it_becomes" + ], + "log": "scratch/review/round23-mutation-flagged_refuses_every_placement.log", + "name": "flagged_refuses_every_placement", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-flagged_refuses_every_placement.json" + }, + { + "changes": [ + { + "after": " person, statutory_blindness=True, prior_disability_periods=()\n", + "before": " person, statutory_blindness=blind, prior_disability_periods=()\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-every_flagged_reads_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/every_flagged_reads_blindness /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_an_ended_current_period_counts_as_the_prior_it_becomes" + ], + "log": "scratch/review/round23-mutation-every_flagged_reads_blindness.log", + "name": "every_flagged_reads_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-every_flagged_reads_blindness.json" + }, + { + "changes": [ + { + "after": " person, statutory_blindness=False, prior_disability_periods=()\n", + "before": " person, statutory_blindness=blind, prior_disability_periods=()\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-every_unflagged_reads_no_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/every_unflagged_reads_no_blindness /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_an_open_flag_keeps_paragraph_b_where_every_placement_meets_it" + ], + "log": "scratch/review/round23-mutation-every_unflagged_reads_no_blindness.log", + "name": "every_unflagged_reads_no_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-every_unflagged_reads_no_blindness.json" + }, + { + "changes": [ + { + "after": " statutory_blindness=True,\n prior_disability_periods=person.prior_disability_periods[:index],\n", + "before": " statutory_blindness=blind,\n prior_disability_periods=person.prior_disability_periods[:index],\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-route_flagged_reads_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/route_flagged_reads_blindness /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_an_ended_current_period_counts_as_the_prior_it_becomes" + ], + "log": "scratch/review/round23-mutation-route_flagged_reads_blindness.log", + "name": "route_flagged_reads_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-route_flagged_reads_blindness.json" + }, + { + "changes": [ + { + "after": " statutory_blindness=False,\n prior_disability_periods=person.prior_disability_periods[:index],\n", + "before": " statutory_blindness=blind,\n prior_disability_periods=person.prior_disability_periods[:index],\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-route_unflagged_reads_no_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/route_unflagged_reads_no_blindness /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_an_open_flag_keeps_paragraph_b_where_every_placement_meets_it" + ], + "log": "scratch/review/round23-mutation-route_unflagged_reads_no_blindness.log", + "name": "route_unflagged_reads_no_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-route_unflagged_reads_no_blindness.json" + }, + { + "changes": [ + { + "after": " person,\n statutory_blindness=blind,\n prior_disability_periods=person.prior_disability_periods[:index],\n", + "before": " person, statutory_blindness=blind, prior_disability_periods=()\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-every_reads_listed_periods.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/every_reads_listed_periods /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_a_later_prior_on_an_earlier_endpoint_binds" + ], + "log": "scratch/review/round23-mutation-every_reads_listed_periods.log", + "name": "every_reads_listed_periods", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-every_reads_listed_periods.json" + }, + { + "changes": [ + { + "after": " prior_disability_periods=(),\n )\n return _witness(\n", + "before": " prior_disability_periods=person.prior_disability_periods[:index],\n )\n return _witness(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-some_drops_earlier_periods.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/some_drops_earlier_periods /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_periods_still_may_not_share_a_day" + ], + "log": "scratch/review/round23-mutation-some_drops_earlier_periods.log", + "name": "some_drops_earlier_periods", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-some_drops_earlier_periods.json" + }, + { + "changes": [ + { + "after": " every = _every_placement_begins(\n person, upper, index, month, exit_month, blind=blind\n )\n", + "before": " every = _every_placement_begins(\n person, lower, index, month, exit_month, blind=blind\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-every_on_upper_credits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/every_on_upper_credits /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_an_unknown_year_can_support_a_prior" + ], + "log": "scratch/review/round23-mutation-every_on_upper_credits.log", + "name": "every_on_upper_credits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-every_on_upper_credits.json" + }, + { + "changes": [ + { + "after": " if _prior_passes(\n person, lower, index, exit_month, blind=blind, **options\n ):\n return blind\n", + "before": " if _prior_passes(\n person, upper, index, exit_month, blind=blind, **options\n ):\n return blind\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-some_on_lower_credits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/some_on_lower_credits /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_an_unknown_year_can_support_a_prior" + ], + "log": "scratch/review/round23-mutation-some_on_lower_credits.log", + "name": "some_on_lower_credits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-some_on_lower_credits.json" + }, + { + "changes": [ + { + "after": " if (\n young and under31_route or subsequent and not young\n ):\n", + "before": " if not ordinary_only and (\n young and under31_route or subsequent and not young\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-ordinary_keeps_special_route.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/ordinary_keeps_special_route /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_period_begun_on_paragraph_c_alone_opens_paragraph_d_after_it" + ], + "log": "scratch/review/round23-mutation-ordinary_keeps_special_route.log", + "name": "ordinary_keeps_special_route", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-ordinary_keeps_special_route.json" + }, + { + "changes": [ + { + "after": " person,\n person.disability_onset,\n _current_period_start_horizon(person, month),\n ) | _prior_sensitive_years(person, binding)\n", + "before": " person, person.disability_onset, start\n ) | _prior_sensitive_years(person, binding)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-fix_reverted.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/fix_reverted /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_partial_years_after_the_start_stay_open" + ], + "log": "scratch/review/round23-mutation-fix_reverted.log", + "name": "fix_reverted", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-fix_reverted.json" + }, + { + "changes": [ + { + "after": " for blind in (True,):\n", + "before": " for blind in (\n (False, True) if _blind_basis(person, index) else (False,)\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-basis_always_blind.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/basis_always_blind /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_prior_basis_split_widens_the_qualifying_quarters" + ], + "log": "scratch/review/round23-mutation-basis_always_blind.log", + "name": "basis_always_blind", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-basis_always_blind.json" + }, + { + "changes": [ + { + "after": " for blind in (False,):\n", + "before": " for blind in (\n (False, True) if _blind_basis(person, index) else (False,)\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-basis_always_nonblind.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/basis_always_nonblind /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_an_open_flag_keeps_paragraph_b_where_every_placement_meets_it" + ], + "log": "scratch/review/round23-mutation-basis_always_nonblind.log", + "name": "basis_always_nonblind", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-basis_always_nonblind.json" + }, + { + "changes": [ + { + "after": " every = _every_placement_begins(\n person, lower, index, month, exit_month, blind=True\n )\n", + "before": " every = _every_placement_begins(\n person, lower, index, month, exit_month, blind=blind\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-binds_ignores_basis.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/binds_ignores_basis /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_prior_basis_split_widens_the_qualifying_quarters" + ], + "log": "scratch/review/round23-mutation-binds_ignores_basis.log", + "name": "binds_ignores_basis", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-binds_ignores_basis.json" + }, + { + "changes": [ + { + "after": " every = _every_placement_begins(\n person, lower, index, month, exit_month, blind=False\n )\n", + "before": " every = _every_placement_begins(\n person, lower, index, month, exit_month, blind=blind\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-binds_always_nonblind.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/binds_always_nonblind /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_an_open_flag_keeps_paragraph_b_where_every_placement_meets_it" + ], + "log": "scratch/review/round23-mutation-binds_always_nonblind.log", + "name": "binds_always_nonblind", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-binds_always_nonblind.json" + }, + { + "changes": [ + { + "after": " _prior_passes(\n person, filling, index, exit_month, blind=True, **options\n )\n and not (\n", + "before": " _prior_passes(\n person, filling, index, exit_month, blind=blind, **options\n )\n and not (\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-keeps_ignores_basis.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/keeps_ignores_basis /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_prior_basis_split_widens_the_qualifying_quarters" + ], + "log": "scratch/review/round23-mutation-keeps_ignores_basis.log", + "name": "keeps_ignores_basis", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-keeps_ignores_basis.json" + }, + { + "changes": [ + { + "after": " _prior_passes(\n person, filling, index, exit_month, blind=False, **options\n )\n and not (\n", + "before": " _prior_passes(\n person, filling, index, exit_month, blind=blind, **options\n )\n and not (\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-keeps_always_nonblind.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/keeps_always_nonblind /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_prior_basis_split_widens_the_qualifying_quarters" + ], + "log": "scratch/review/round23-mutation-keeps_always_nonblind.log", + "name": "keeps_always_nonblind", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-keeps_always_nonblind.json" + }, + { + "changes": [ + { + "after": " return True\n", + "before": " _refuse(\n InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY,\n \"No annual placement supports a listed prior's first insured quarter\",\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-no_support_stands.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/no_support_stands /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_flagged_prior_needs_paragraph_c_without_paragraph_b" + ], + "log": "scratch/review/round23-mutation-no_support_stands.log", + "name": "no_support_stands", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-no_support_stands.json" + }, + { + "changes": [ + { + "after": " _prior_passes(\n person, upper, index, exit_month, blind=True, **options\n )\n and not _every_placement_begins(\n", + "before": " _prior_passes(\n person, upper, index, exit_month, blind=False, **options\n )\n and not _every_placement_begins(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-flagged_support_reads_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/flagged_support_reads_blindness /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_only_a_middle_completion_fits_a_flag[0-InsuredTest.ALL-InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY-No" + ], + "log": "scratch/review/round23-mutation-flagged_support_reads_blindness.log", + "name": "flagged_support_reads_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-flagged_support_reads_blindness.json" + }, + { + "changes": [ + { + "after": " and not _every_placement_begins(\n person,\n lower,\n index,\n month,\n exit_month,\n blind=True,\n ordinary_only=True,\n **options,\n )\n", + "before": " and not _every_placement_begins(\n person,\n lower,\n index,\n month,\n exit_month,\n blind=False,\n ordinary_only=True,\n **options,\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-flagged_ordinary_reads_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/flagged_ordinary_reads_blindness /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_an_ended_current_period_counts_as_the_prior_it_becomes" + ], + "log": "scratch/review/round23-mutation-flagged_ordinary_reads_blindness.log", + "name": "flagged_ordinary_reads_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-flagged_ordinary_reads_blindness.json" + }, + { + "changes": [ + { + "after": " _prior_passes(\n person, lower, index, exit_month, blind=False, **options\n )\n and not _every_placement_begins(\n", + "before": " _prior_passes(\n person, upper, index, exit_month, blind=False, **options\n )\n and not _every_placement_begins(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-flagged_support_on_lower_credits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/flagged_support_on_lower_credits /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_only_a_middle_completion_fits_a_flag[None-InsuredTest.FULLY-InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY-Annual" + ], + "log": "scratch/review/round23-mutation-flagged_support_on_lower_credits.log", + "name": "flagged_support_on_lower_credits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-flagged_support_on_lower_credits.json" + }, + { + "changes": [ + { + "after": " and not _every_placement_begins(\n person,\n upper,\n index,\n month,\n exit_month,\n blind=False,\n ordinary_only=True,\n **options,\n )\n", + "before": " and not _every_placement_begins(\n person,\n lower,\n index,\n month,\n exit_month,\n blind=False,\n ordinary_only=True,\n **options,\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-flagged_ordinary_on_upper_credits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/flagged_ordinary_on_upper_credits /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_only_a_middle_completion_fits_a_flag[None-InsuredTest.FULLY-InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY-Annual" + ], + "log": "scratch/review/round23-mutation-flagged_ordinary_on_upper_credits.log", + "name": "flagged_ordinary_on_upper_credits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-flagged_ordinary_on_upper_credits.json" + }, + { + "changes": [ + { + "after": " bases = tuple(\n _prior_basis(person, lower, upper, index, month, coverage_end_month)\n for index in range(0 if current_unknown else len(person.prior_disability_periods))\n )\n", + "before": " bases = tuple(\n _prior_basis(person, lower, upper, index, month, coverage_end_month)\n for index in range(len(person.prior_disability_periods))\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-basis_skipped_on_open_period.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/basis_skipped_on_open_period /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_flagged_prior_needs_paragraph_c_without_paragraph_b" + ], + "log": "scratch/review/round23-mutation-basis_skipped_on_open_period.log", + "name": "basis_skipped_on_open_period", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-basis_skipped_on_open_period.json" + }, + { + "changes": [ + { + "after": " (index, True)\n for index, blind in enumerate(bases)\n", + "before": " (index, blind)\n for index, blind in enumerate(bases)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-binding_pair_drops_basis.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/binding_pair_drops_basis /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_prior_basis_split_widens_the_qualifying_quarters" + ], + "log": "scratch/review/round23-mutation-binding_pair_drops_basis.log", + "name": "binding_pair_drops_basis", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-binding_pair_drops_basis.json" + }, + { + "changes": [ + { + "after": " bases = tuple(\n _prior_basis(person, lower, upper, index, month, coverage_end_month)\n for index in range(len(person.prior_disability_periods) if test in (InsuredTest.ALL, InsuredTest.DISABILITY) else 0)\n )\n", + "before": " bases = tuple(\n _prior_basis(person, lower, upper, index, month, coverage_end_month)\n for index in range(len(person.prior_disability_periods))\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-basis_only_on_disability.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/basis_only_on_disability /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_only_a_middle_completion_fits_a_flag[None-InsuredTest.FULLY-InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY-Annual" + ], + "log": "scratch/review/round23-mutation-basis_only_on_disability.log", + "name": "basis_only_on_disability", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-basis_only_on_disability.json" + }, + { + "changes": [ + { + "after": " return not every or _prior_passes(\n person, upper, index, exit_month, blind=True, ordinary_only=True\n )\n", + "before": " return not every or _prior_passes(\n person, upper, index, exit_month, blind=False, ordinary_only=True\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-binds_flag_reads_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/binds_flag_reads_blindness /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_an_unknown_year_leaves_a_special_prior_every_placement_carries" + ], + "log": "scratch/review/round23-mutation-binds_flag_reads_blindness.log", + "name": "binds_flag_reads_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-binds_flag_reads_blindness.json" + }, + { + "changes": [ + { + "after": " return not every or _prior_passes(\n person, lower, index, exit_month, blind=False, ordinary_only=True\n )\n", + "before": " return not every or _prior_passes(\n person, upper, index, exit_month, blind=False, ordinary_only=True\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-binds_flag_on_lower_credits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/binds_flag_on_lower_credits /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_an_unknown_year_can_carry_a_flagged_prior_past_the_ordinary_rule" + ], + "log": "scratch/review/round23-mutation-binds_flag_on_lower_credits.log", + "name": "binds_flag_on_lower_credits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-binds_flag_on_lower_credits.json" + }, + { + "changes": [ + { + "after": " and not (\n person.prior_disability_periods[index].special_insured\n and _prior_passes(\n person,\n filling,\n index,\n exit_month,\n blind=True,\n ordinary_only=True,\n **options,\n )\n )\n", + "before": " and not (\n person.prior_disability_periods[index].special_insured\n and _prior_passes(\n person,\n filling,\n index,\n exit_month,\n blind=False,\n ordinary_only=True,\n **options,\n )\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-keeps_flag_reads_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/keeps_flag_reads_blindness /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_period_begun_in_the_age_31_quarter_rests_on_paragraph_d" + ], + "log": "scratch/review/round23-mutation-keeps_flag_reads_blindness.log", + "name": "keeps_flag_reads_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-keeps_flag_reads_blindness.json" + }, + { + "changes": [ + { + "after": " if binding:\n favored_rows, _ = _world(", + "before": " if lo_start is not None or binding:\n favored_rows, _ = _world(" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-remove_first_start_check.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/remove_first_start_check /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[109307]" + ], + "log": "scratch/review/round23-mutation-remove_first_start_check.log", + "name": "remove_first_start_check", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-remove_first_start_check.json" + }, + { + "changes": [ + { + "after": " if False and any(\n _improves(outcome, returned, last_insured)\n for outcome in _period_outcomes(", + "before": " if any(\n _improves(outcome, returned, last_insured)\n for outcome in _period_outcomes(" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-drop_bound_refusal.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/drop_bound_refusal /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[109307]" + ], + "log": "scratch/review/round23-mutation-drop_bound_refusal.log", + "name": "drop_bound_refusal", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-drop_bound_refusal.json" + }, + { + "changes": [ + { + "after": " \"dated\": False,\n \"last_insured\": None,\n", + "before": " \"dated\": dli is not None,\n \"last_insured\": dli.upper if dli is not None else None,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-drop_dli_comparison.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/drop_dli_comparison /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_frozen_exit_refuses" + ], + "log": "scratch/review/round23-mutation-drop_dli_comparison.log", + "name": "drop_dli_comparison", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-drop_dli_comparison.json" + }, + { + "changes": [ + { + "after": " return _every_placement_passes(\n person, credits, start, month, exit_month, InsuredTest.DISABILITY\n )", + "before": " return not person.prior_disability_periods and _every_placement_passes(\n person, credits, start, month, exit_month, InsuredTest.DISABILITY\n )" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-start_fixed_ignores_priors.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/start_fixed_ignores_priors /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_current_period_after_that_prior_refuses" + ], + "log": "scratch/review/round23-mutation-start_fixed_ignores_priors.log", + "name": "start_fixed_ignores_priors", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-start_fixed_ignores_priors.json" + }, + { + "changes": [ + { + "after": " horizon = _current_period_start_horizon(person, month)\n for quarter in range(_qid(start), _qid(start) + 1):\n try:\n completed, own_start = _complete_current_period(", + "before": " horizon = _current_period_start_horizon(person, month)\n for quarter in range(_qid(start), _qid(horizon) + 1):\n try:\n completed, own_start = _complete_current_period(" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-bound_stops_at_reported_start.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/bound_stops_at_reported_start /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[109307]" + ], + "log": "scratch/review/round23-mutation-bound_stops_at_reported_start.log", + "name": "bound_stops_at_reported_start", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-bound_stops_at_reported_start.json" + }, + { + "changes": [ + { + "after": " if not ordinary_only and (\n young or subsequent and not young\n ):\n", + "before": " if not ordinary_only and (\n young and under31_route or subsequent and not young\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-unflagged_reads_paragraph_c.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/unflagged_reads_paragraph_c /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_prior_basis_split_widens_the_qualifying_quarters" + ], + "log": "scratch/review/round23-mutation-unflagged_reads_paragraph_c.log", + "name": "unflagged_reads_paragraph_c", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-unflagged_reads_paragraph_c.json" + }, + { + "changes": [ + { + "after": " if not ordinary_only and (\n young and under31_route or subsequent\n ):\n", + "before": " if not ordinary_only and (\n young and under31_route or subsequent and not young\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-young_takes_subsequent_route.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/young_takes_subsequent_route /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_young_prior_after_a_flagged_one_rests_on_paragraph_b" + ], + "log": "scratch/review/round23-mutation-young_takes_subsequent_route.log", + "name": "young_takes_subsequent_route", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-young_takes_subsequent_route.json" + }, + { + "changes": [ + { + "after": " if not ordinary_only and (\n under31_route and (young or subsequent)\n ):\n", + "before": " if not ordinary_only and (\n young and under31_route or subsequent and not young\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-unflagged_drops_paragraph_d.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/unflagged_drops_paragraph_d /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_prior_past_31_after_a_flagged_one_can_rest_on_paragraph_d" + ], + "log": "scratch/review/round23-mutation-unflagged_drops_paragraph_d.log", + "name": "unflagged_drops_paragraph_d", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-unflagged_drops_paragraph_d.json" + }, + { + "changes": [ + { + "after": " InsuredTest.DISABILITY,\n under31_route=True,\n **options,\n )[0]\n", + "before": " InsuredTest.DISABILITY,\n under31_route=period.special_insured,\n **options,\n )[0]\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-route_reads_paragraph_c.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/route_reads_paragraph_c /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_an_open_flag_keeps_paragraph_b_where_every_placement_meets_it" + ], + "log": "scratch/review/round23-mutation-route_reads_paragraph_c.log", + "name": "route_reads_paragraph_c", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-route_reads_paragraph_c.json" + }, + { + "changes": [ + { + "after": " InsuredTest.DISABILITY,\n under31_route=True,\n **options,\n )\n\n", + "before": " InsuredTest.DISABILITY,\n under31_route=period.special_insured,\n **options,\n )\n\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-every_reads_paragraph_c.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/every_reads_paragraph_c /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_prior_basis_split_widens_the_qualifying_quarters" + ], + "log": "scratch/review/round23-mutation-every_reads_paragraph_c.log", + "name": "every_reads_paragraph_c", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-every_reads_paragraph_c.json" + }, + { + "changes": [ + { + "after": " InsuredTest.DISABILITY,\n under31_route=False,\n **options,\n )[0]\n", + "before": " InsuredTest.DISABILITY,\n under31_route=period.special_insured,\n **options,\n )[0]\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-route_drops_flagged_paragraph_c.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/route_drops_flagged_paragraph_c /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_an_ended_current_period_counts_as_the_prior_it_becomes" + ], + "log": "scratch/review/round23-mutation-route_drops_flagged_paragraph_c.log", + "name": "route_drops_flagged_paragraph_c", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-route_drops_flagged_paragraph_c.json" + }, + { + "changes": [ + { + "after": " InsuredTest.DISABILITY,\n under31_route=False,\n **options,\n )\n\n", + "before": " InsuredTest.DISABILITY,\n under31_route=period.special_insured,\n **options,\n )\n\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-every_drops_flagged_paragraph_c.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/every_drops_flagged_paragraph_c /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_an_unknown_year_can_carry_a_flagged_prior_past_the_ordinary_rule" + ], + "log": "scratch/review/round23-mutation-every_drops_flagged_paragraph_c.log", + "name": "every_drops_flagged_paragraph_c", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-every_drops_flagged_paragraph_c.json" + }, + { + "changes": [ + { + "after": " ordinary_only=False,\n under31_route=False,\n):\n", + "before": " ordinary_only=False,\n under31_route=True,\n):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-current_drops_paragraph_c.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/current_drops_paragraph_c /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_period_begun_on_paragraph_c_alone_opens_paragraph_d_after_it" + ], + "log": "scratch/review/round23-mutation-current_drops_paragraph_c.log", + "name": "current_drops_paragraph_c", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-current_drops_paragraph_c.json" + }, + { + "changes": [ + { + "after": " return _complete_current_period(person, quarter, special=False)\n", + "before": " return _complete_current_period(person, quarter, special=special is True)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-m1_flag.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/m1_flag /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_period_begun_on_paragraph_c_alone_opens_paragraph_d_after_it" + ], + "log": "scratch/review/round23-mutation-m1_flag.log", + "name": "m1_flag", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-m1_flag.json" + }, + { + "changes": [ + { + "after": " if i and _qid(period.start) <= _qid(periods[i - 1].end):\n", + "before": " if i and period.start <= periods[i - 1].end:\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-m2_listed.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/m2_listed /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_rs00301_140_example_7_begins_on_the_onset_day" + ], + "log": "scratch/review/round23-mutation-m2_listed.log", + "name": "m2_listed", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-m2_listed.json" + }, + { + "changes": [ + { + "after": " and _qid(period.end) >= _qid(person.disability_onset)\n", + "before": " and period.end >= person.disability_onset\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-m2_current.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/m2_current /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_rs00301_140_example_7_begins_on_the_onset_day" + ], + "log": "scratch/review/round23-mutation-m2_current.log", + "name": "m2_current", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-m2_current.json" + }, + { + "changes": [ + { + "after": " through_quarter=min(qid, _qid(exit_month)) if exit_month else qid,\n", + "before": " through_quarter=qid,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-m3_exit.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/m3_exit /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_an_open_flag_keeps_paragraph_b_where_every_placement_meets_it" + ], + "log": "scratch/review/round23-mutation-m3_exit.log", + "name": "m3_exit", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-m3_exit.json" + }, + { + "changes": [ + { + "after": " allowed = tuple(q for q in allowed if q >= _qid(person.birth_date))\n rows[year] = (fixed, flexible, allowed)\n return rows, periods\n", + "before": " rows[year] = (fixed, flexible, allowed)\n return rows, periods\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-m13_birth.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/m13_birth /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_birth_year_credits_quarters_before_the_birth" + ], + "log": "scratch/review/round23-mutation-m13_birth.log", + "name": "m13_birth", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-m13_birth.json" + }, + { + "changes": [ + { + "after": " first = 0\n", + "before": " first = -_qid(quarter) if disability and witness[0] else 0\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-m4_rank.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/m4_rank /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_binding_prior_keeps_the_earliest_qualifying_quarter" + ], + "log": "scratch/review/round23-mutation-m4_rank.log", + "name": "m4_rank", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-m4_rank.json" + }, + { + "changes": [ + { + "after": " maximum_qcs if broad else None,\n earliest=None,\n", + "before": " maximum_qcs if broad else None,\n earliest=earliest,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-m5_earliest.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/m5_earliest /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_unknown_priors_reach_the_onset_quarter" + ], + "log": "scratch/review/round23-mutation-m5_earliest.log", + "name": "m5_earliest", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-m5_earliest.json" + }, + { + "changes": [ + { + "after": " if False\n and not for_disability\n", + "before": " if living\n and not for_disability\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-m6_men.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/m6_men /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_the_404_115_table_gives_each_cohort_its_count" + ], + "log": "scratch/review/round23-mutation-m6_men.log", + "name": "m6_men", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-m6_men.json" + }, + { + "changes": [ + { + "after": " ):\n return False\n", + "before": " and _flag_fits(\n person, lower, upper, index, month, exit_month, **options\n )\n ):\n return False\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-m7_flagfits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/m7_flagfits /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_flagged_prior_needs_paragraph_c_without_paragraph_b" + ], + "log": "scratch/review/round23-mutation-m7_flagfits.log", + "name": "m7_flagfits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-m7_flagfits.json" + }, + { + "changes": [ + { + "after": " try:\n pass\n except InsuredConfigurationUnsupported:\n", + "before": " try:\n _refuse_unsupported_priors(\n person, lower, upper, month, coverage_end_month\n )\n except InsuredConfigurationUnsupported:\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-precedence_possible.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/precedence_possible /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_an_unsupported_prior_refuses_before_unknown_earnings[0]" + ], + "log": "scratch/review/round23-mutation-precedence_possible.log", + "name": "precedence_possible", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-precedence_possible.json" + }, + { + "changes": [ + { + "after": " if unknown:\n", + "before": " if unknown:\n _refuse_unsupported_priors(\n person, lower, upper, month, coverage_end_month\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-precedence_unknown.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/precedence_unknown /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_an_unsupported_prior_refuses_before_unknown_earnings[None]" + ], + "log": "scratch/review/round23-mutation-precedence_unknown.log", + "name": "precedence_unknown", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-precedence_unknown.json" + }, + { + "changes": [ + { + "after": " counts = [(lower[y][1], upper[y][1]) for y in open_years]\n", + "before": " counts = [range(lower[y][1], upper[y][1] + 1) for y in open_years]\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-flag_middle.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/flag_middle /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_only_a_middle_completion_fits_a_flag[None-InsuredTest.FULLY-InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY-Annual" + ], + "log": "scratch/review/round23-mutation-flag_middle.log", + "name": "flag_middle", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-flag_middle.json" + }, + { + "changes": [ + { + "after": " 1960 * 4 + 2,\n", + "before": " min(_qid(covered), 1960 * 4 + 2),\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-pre1956_scan.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/pre1956_scan /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_pre1956_listed_prior_rests_on_rs00301_480[later1-InsuredUnsupportedReason.DISABILITY_BEFORE_1956-RS00301.480" + ], + "log": "scratch/review/round23-mutation-pre1956_scan.log", + "name": "pre1956_scan", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-pre1956_scan.json" + }, + { + "changes": [ + { + "after": " ):\n pass\n _refuse(\n InsuredUnsupportedReason.DISABILITY_BEFORE_1956,\n", + "before": " ):\n return None\n _refuse(\n InsuredUnsupportedReason.DISABILITY_BEFORE_1956,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-pre1956_none.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/pre1956_none /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_pre1956_listed_prior_rests_on_rs00301_480[later2-None-None]" + ], + "log": "scratch/review/round23-mutation-pre1956_none.log", + "name": "pre1956_none", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-pre1956_none.json" + }, + { + "changes": [ + { + "after": " raise error from None\n _refuse(\n InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY,\n \"First insured start depends on annual placement or prior treatment\",\n", + "before": " raise error from None\n _refuse(\n InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY,\n \"Annual placement decides a listed prior's first insured quarter\",\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-nit29.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/nit29 /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_split_start_names_the_listed_prior" + ], + "log": "scratch/review/round23-mutation-nit29.log", + "name": "nit29", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-nit29.json" + }, + { + "changes": [ + { + "after": " and self.current_disability_period_end > fra_end + timedelta(days=9999)\n", + "before": " and self.current_disability_period_end > fra_end\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-low12.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/low12 /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_declared_dates_past_the_statutory_end_are_input_errors" + ], + "log": "scratch/review/round23-mutation-low12.log", + "name": "low12", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-low12.json" + }, + { + "changes": [ + { + "after": " and self.dib_entitlement_month > fra.replace(day=1)\n", + "before": " and self.dib_entitlement_month >= fra.replace(day=1)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-low16_dib.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/low16_dib /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_entitlement_months_must_be_possible[dib_entitlement_month-month1-at" + ], + "log": "scratch/review/round23-mutation-low16_dib.log", + "name": "low16_dib", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-low16_dib.json" + }, + { + "changes": [ + { + "after": " < _attain(self.birth_date, 62).replace(day=1) - timedelta(days=31)\n", + "before": " < _attain(self.birth_date, 62).replace(day=1)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-low16_rib.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/low16_rib /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_entitlement_months_must_be_possible[rib_entitlement_month-month4-before" + ], + "log": "scratch/review/round23-mutation-low16_rib.log", + "name": "low16_rib", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-low16_rib.json" + }, + { + "changes": [ + { + "after": " and True\n", + "before": " and _qdate(_qid(_attain(person.birth_date, 31))) < date(1983, 5, 1)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-low19.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/low19 /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_the_pre_1983_refusal_needs_31_before_may_1983" + ], + "log": "scratch/review/round23-mutation-low19.log", + "name": "low19", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-low19.json" + }, + { + "changes": [ + { + "after": " It runs the person and query checks ``insured_status`` runs.\n \"\"\"\n", + "before": " It runs the person and query checks ``insured_status`` runs.\n \"\"\"\n _validate_person_at(person, month)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-low23.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/low23 /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_the_requirement_helper_checks_what_insured_status_checks" + ], + "log": "scratch/review/round23-mutation-low23.log", + "name": "low23", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-low23.json" + }, + { + "changes": [ + { + "after": " (row.quarterly_wages, cutoff, \"Quarterly earnings\"),\n", + "before": " (row.quarterly_wages, paid, \"Quarterly earnings\"),\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-low24.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/low24 /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_wages_paid_after_death_count_toward_the_year" + ], + "log": "scratch/review/round23-mutation-low24.log", + "name": "low24", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-low24.json" + }, + { + "changes": [ + { + "after": " raise InvalidFamilyInput(f\"{label} declared after coverage ends\")\n", + "before": " raise InvalidFamilyInput(f\"{label} declared before birth\")\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-nit25.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/nit25 /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_quarterly_bounds_name_themselves[1960-declared0-QCs" + ], + "log": "scratch/review/round23-mutation-nit25.log", + "name": "nit25", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-nit25.json" + }, + { + "changes": [ + { + "after": " return not period.special_insured\n", + "before": " return not period.special_insured and period.start >= date(1973, 1, 1)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-low21.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/low21 /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_an_unsupported_prior_refuses_before_unknown_earnings[None]" + ], + "log": "scratch/review/round23-mutation-low21.log", + "name": "low21", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-low21.json" + }, + { + "changes": [ + { + "after": " if False:\n _settle_current_basis(\n", + "before": " if lo_start is not None and not prior_unknown:\n _settle_current_basis(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-m1_settle.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/m1_settle /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_placement_or_year_that_decides_the_basis_refuses" + ], + "log": "scratch/review/round23-mutation-m1_settle.log", + "name": "m1_settle", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-m1_settle.json" + }, + { + "changes": [ + { + "after": " ordinary_only=True,\n ):\n return False\n return False\n", + "before": " ordinary_only=True,\n ):\n return False\n return None\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-m1_open_basis.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/m1_open_basis /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_placement_or_year_that_decides_the_basis_refuses" + ], + "log": "scratch/review/round23-mutation-m1_open_basis.log", + "name": "m1_open_basis", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-m1_open_basis.json" + }, + { + "changes": [ + { + "after": " )\n if len(elapsed) < 15:\n window, required = (\n _window(end, 12, periods, boundary),\n", + "before": " )\n if len(elapsed) < 12:\n window, required = (\n _window(end, 12, periods, boundary),\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-first_onset_short.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/first_onset_short /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_each_published_first_onset_reproduces[rs140-joseph-6]" + ], + "log": "scratch/review/round23-mutation-first_onset_short.log", + "name": "first_onset_short", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-first_onset_short.json" + }, + { + "changes": [ + { + "after": " else:\n window, required = elapsed, max(6, (len(elapsed) + 1) // 2)\n candidates.append(\n", + "before": " else:\n window, required = elapsed, max(6, len(elapsed) // 2)\n candidates.append(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-first_onset_odd.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/first_onset_odd /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_period_begun_on_paragraph_c_alone_opens_paragraph_d_after_it" + ], + "log": "scratch/review/round23-mutation-first_onset_odd.log", + "name": "first_onset_odd", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-first_onset_odd.json" + }, + { + "changes": [ + { + "after": " (\"prior_disability_period_basis\", False),\n", + "before": " (\"prior_disability_period_basis\", basis_split),\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-basis_split_unreported.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/basis_split_unreported /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_prior_basis_split_widens_the_qualifying_quarters" + ], + "log": "scratch/review/round23-mutation-basis_split_unreported.log", + "name": "basis_split_unreported", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-basis_split_unreported.json" + }, + { + "changes": [ + { + "after": " (\"prior_disability_period_basis\", True),\n", + "before": " (\"prior_disability_period_basis\", basis_split),\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-basis_split_always.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/basis_split_always /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_binding_prior_keeps_the_earliest_qualifying_quarter" + ], + "log": "scratch/review/round23-mutation-basis_split_always.log", + "name": "basis_split_always", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-basis_split_always.json" + }, + { + "changes": [ + { + "after": " living = person.death_date is None\n", + "before": " living = person.death_date is None or person.death_date > at\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-m4_living.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/m4_living /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_death_after_the_query_keeps_the_living_count" + ], + "log": "scratch/review/round23-mutation-m4_living.log", + "name": "m4_living", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-m4_living.json" + }, + { + "changes": [ + { + "after": " if person.statutory_blindness or _qid(quarter) > _qid(\n", + "before": " if person.statutory_blindness or _qid(quarter) >= _qid(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-m8_age31.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/m8_age31 /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_period_begun_in_the_age_31_quarter_rests_on_paragraph_d" + ], + "log": "scratch/review/round23-mutation-m8_age31.log", + "name": "m8_age31", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-m8_age31.json" + }, + { + "changes": [ + { + "after": " if period.end > fra_end + timedelta(days=9999):\n # The same 404.321 end binds a listed prior.\n", + "before": " if period.end > fra_end:\n # The same 404.321 end binds a listed prior.\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-low12_prior.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/low12_prior /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_declared_dates_past_the_statutory_end_are_input_errors" + ], + "log": "scratch/review/round23-mutation-low12_prior.log", + "name": "low12_prior", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-low12_prior.json" + }, + { + "changes": [ + { + "after": "return _complete_current_period(person, quarter, special=special is not False)", + "before": "return _complete_current_period(person, quarter, special=special is True)" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-open_flag_as_special.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/open_flag_as_special /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_an_open_flag_keeps_paragraph_b_where_every_placement_meets_it" + ], + "log": "scratch/review/round23-mutation-open_flag_as_special.log", + "name": "open_flag_as_special", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-open_flag_as_special.json" + }, + { + "changes": [ + { + "after": " if len(found) == 1:\n", + "before": " if len(found) == 1 and None not in found:\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-settle_accepts_open_flag.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/settle_accepts_open_flag /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_placement_or_year_that_decides_the_basis_refuses" + ], + "log": "scratch/review/round23-mutation-settle_accepts_open_flag.log", + "name": "settle_accepts_open_flag", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-settle_accepts_open_flag.json" + }, + { + "changes": [ + { + "after": "return not period.special_insured and period.start >= date(1972, 1, 1)", + "before": "return not period.special_insured and period.start >= date(1973, 1, 1)" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-blind_basis_1972.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/blind_basis_1972 /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_past_blindness_begins_a_prior_only_from_1973[start0-False]" + ], + "log": "scratch/review/round23-mutation-blind_basis_1972.log", + "name": "blind_basis_1972", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-blind_basis_1972.json" + }, + { + "changes": [ + { + "after": " if False:\n", + "before": " if earliest is not None and hi[0]:\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-no_earliest_widening.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/no_earliest_widening /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_unknown_priors_reach_the_onset_quarter" + ], + "log": "scratch/review/round23-mutation-no_earliest_widening.log", + "name": "no_earliest_widening", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-no_earliest_widening.json" + }, + { + "changes": [ + { + "after": " return True\n return True\n binding = ((index, False),)\n sensitive = _prior_sensitive_years(person, binding)\n", + "before": " return True\n binding = ((index, False),)\n sensitive = _prior_sensitive_years(person, binding)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round23 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round23 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND23_MUTATION=scratch/review/round23-mutation-flag_fits_always.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp23/flag_fits_always /tmp/tbvenv/bin/python scratch/review/run_round23_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_flagged_prior_needs_paragraph_c_without_paragraph_b" + ], + "log": "scratch/review/round23-mutation-flag_fits_always.log", + "name": "flag_fits_always", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "spec_path": "scratch/review/round23-mutation-flag_fits_always.json" + } + ], + "round_23_runner_source": "\"\"\"Run named invented-data conformance tests with open-event auditing.\"\"\"\n\nimport hashlib\nimport json\nimport os\nfrom pathlib import Path\nimport sys\n\nCOUNTS = {\"restricted_opens\": 0, \"subprocess.Popen\": 0, \"os.system\": 0}\nBARRED = {\n \"gates.yaml\", \"adjusted_poverty.py\", \"rows.py\",\n \"ssa_trust_fund_interest_rates_2026.json\",\n \"urban2010_cola_comparison.md\", \"urban2010_fra68_comparison.md\",\n \"boomers2004_uniform_cut_comparison.md\", \"minimum_benefits_comparison.md\",\n \"m6_projection_engine.md\", \"mint8_table_user_guide.source.html\",\n \"test_anchor_provenance_erratum.py\",\n \"s0_1_power_results.json\", \"s0_1_source_audit.md\", \"s0_1_power.py\",\n \"test_s0_1_invariants.py\", \"test_s0_1_power.py\",\n \"test_s0_1_thresholds.py\",\n}\n\n\ndef audit(event, arguments):\n if event == \"open\" and isinstance(arguments[0], (str, bytes)):\n path = os.fsdecode(arguments[0])\n name = Path(path).name\n if (\n name in BARRED\n or name.startswith((\"adjusted_poverty.\", \"rows.\"))\n or \"/PolicyEngine/psid-data/\" in path\n or \"/microcosm-launch-evidence/\" in path\n or \"/dynasim-refs/\" in path\n or \"/claude-501/\" in path\n or \"/tests/s0_1/\" in path\n or \"/tests/acola_track/\" in path\n or \"/tests/cola_track_a/\" in path\n or \"/tests/fra68_track/\" in path\n ):\n COUNTS[\"restricted_opens\"] += 1\n raise RuntimeError(path)\n elif event in (\"subprocess.Popen\", \"os.system\"):\n COUNTS[event] += 1\n\n\ndef main():\n for name in (\"POPULACE_DYNAMICS_PSID_DIR\", \"POPULACE_DYNAMICS_EPUF_DIR\"):\n assert os.environ[name] == \"/nonexistent/trackb-round23\"\n assert sys.argv[1:]\n assert all(\n not argument.startswith(\"tests/\") or \".py\" in argument\n for argument in sys.argv[1:]\n )\n sys.addaudithook(audit)\n from populace_dynamics.track_b import insured_status as insured\n\n source_path = Path(insured.__file__)\n original = source_path.read_bytes()\n baseline_path = os.environ.get(\"TRACKB_ROUND16_SOURCE\")\n if baseline_path:\n baseline = Path(baseline_path).read_bytes()\n exec(compile(baseline, str(source_path), \"exec\"), insured.__dict__)\n print(\"BASELINE\", hashlib.sha256(baseline).hexdigest(), flush=True)\n spec_path = os.environ.get(\"TRACKB_ROUND23_MUTATION\")\n if spec_path:\n spec = json.loads(Path(spec_path).read_text())\n assert hashlib.sha256(original).hexdigest() == spec[\"source_sha256\"]\n source = original.decode()\n for change in spec[\"changes\"]:\n assert source.count(change[\"before\"]) == 1, change[\"before\"]\n source = source.replace(change[\"before\"], change[\"after\"], 1)\n exec(compile(source, str(source_path), \"exec\"), insured.__dict__)\n print(\"MUTATION\", spec[\"name\"], flush=True)\n import pytest\n\n try:\n return pytest.main(sys.argv[1:])\n finally:\n assert source_path.read_bytes() == original\n print(\"OPEN_AUDIT\", json.dumps(COUNTS, sort_keys=True), flush=True)\n\n\nif __name__ == \"__main__\":\n raise SystemExit(main())\n", + "round_23_note": "A cloud session ran round 23's 107 mutations at f32d8812, the last round 23 head, against every insured status module, with no restricted open (PR #562 comment 6618201683). The 107 are round 22's 70, 17 of them re-derived where round 23 rewrote their code, and 37 of round 23's own. All 107 failed a named test.", + "round_23_test_sha256": { + "tests/test_track_b_insured_status.py": "f192edffae4bacd9b6ca3df1ace9daef1e3e4bde3878071134f134c4a467dd47", + "tests/test_track_b_insured_status_classification_oracle.py": "a00b76d2428ecaebcaf1d2e3626c4022e10ea20c70b12e810c24f7ea822d4574", + "tests/test_track_b_insured_status_contract.py": "e90b6ad6230962d19f5b5f25d0c1bb3b34ad22dda3f9bc9092c34122f45df996", + "tests/test_track_b_insured_status_fix_round_10.py": "8be66f8f40f2e7ed5a72b9d872e36abfc83e311a64bb0afb33f03f1f81ba1c0c", + "tests/test_track_b_insured_status_fix_round_11.py": "3a8186d7543c06ccbc8844d37dd994e48a5d62e9749640376af124fcbadd77e1", + "tests/test_track_b_insured_status_fix_round_12.py": "39a45f57ed5238b2d0e33c0c45edbae083ccaba528ec5c4d8639eec6c7919bb5", + "tests/test_track_b_insured_status_fix_round_13.py": "7a27c087879ab2c7e6d3b0b3e5e5de5e968f5874c4b08fdd6e007b98e67cccfc", + "tests/test_track_b_insured_status_fix_round_14.py": "cbcc071ad21e444743785a35bc1d857159a1b2a6c4b808d5d7c9540fbe4bf6e9", + "tests/test_track_b_insured_status_fix_round_17.py": "ca52eef0196d6a5f6048ffd5ec59ceee53ba24f90662d6b6efc296e4cf73873d", + "tests/test_track_b_insured_status_fix_round_22.py": "4501efa1c9864ddd802c9be8836d7f3ff8dade677a890da596d7a8fb68977ef9", + "tests/test_track_b_insured_status_fix_round_23.py": "c62b0088c4c904e8847325189f7a7b693d9b3a9df182973ea9a875edbf382917", + "tests/test_track_b_insured_status_fix_round_3_periods.py": "81106394a87c15bd852d38b90f40ad9d803013cb898c077a31e70f24cbfb7b23", + "tests/test_track_b_insured_status_fix_round_4_routes.py": "806e52f991a0bf3501f8f900a568a6749c37da85e41ae746f96a98f66fa1618c", + "tests/test_track_b_insured_status_fix_round_5_possibility.py": "e219c0a5753a3cef9676876380e9dfaf11f355160f8f3bd9459083def5569c07", + "tests/test_track_b_insured_status_fix_round_6_ordering.py": "bcd87fac4e9700930e31a5b1e42e1f6c962aabd759a58bb6bcbec85bb6e5fc4d", + "tests/test_track_b_insured_status_fix_round_6_routes.py": "0cd626b7cc0b60d5443c74e3f1df003ce8d003f63d8ed12df951a49854aa5e1a", + "tests/test_track_b_insured_status_fix_round_8.py": "b42a022f57321a230d7f514c8acda04197a98a6e34aa2d7ed082e6813b52d4c4", + "tests/test_track_b_insured_status_qc.py": "02470d309062130c6a6827bdc6bb475c4e46be845a5e0439f9729327a1d7d5c3", + "tests/test_track_b_insured_status_sources.py": "f37a0689a5d45496af935dac0d4e0f8809a78e52fd0bcb3e00b529849893e1d5", + "tests/test_track_b_insured_status_status_oracle.py": "fb8ac883d856a2240de198ddff7a514c6d41e0ff08b600fc6283d05d1d5a64cb", + "tests/test_track_b_insured_status_status_stress.py": "882e3b1f0a1c91fd126d8ba85da50fd7672b475b13b81eb48e132d470cd27bed", + "tests/test_track_b_insured_status_fix_round_19.py": "735433c50e252f3bfcdc4c11019c52d750ddfe97dbb3195d3e51bff511175b59", + "tests/test_track_b_insured_status_fix_round_2.py": "c1d00971949eb7d1f9ac458dfea1b5e47922fb3d0047a50a764e7400f9321835", + "tests/test_track_b_insured_status_fix_round_20.py": "f15ef8610de8fb6138f485588ff188c6748e34ebd5cb51ee2f55735d2fa9c4cd", + "tests/test_track_b_insured_status_fix_round_21.py": "dd858c630cbd0473745568cdcf92ac28b350bd4efe06e35f5be1f4c264b3aa04" + }, + "round_23_replay": "Write round_23_runner_source to scratch/review/run_round23_named.py. For each round_23_mutations record, write name/source_sha256/changes to its spec_path, then execute its exact command at f32d8812. Mutations apply only in memory.", + "round_23_final_source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab" } From c81036b6c57be4e59f35565ae54e7d2efdf682a2 Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Fri, 6 Nov 2026 05:03:20 -0500 Subject: [PATCH 46/46] Record round 24's 135 cloud mutation kills (#562) Cloud brief 6931 ran round 24's 135 mutations at d30e4426 through every insured status module (PR #562 comment 6620539979). All 135 failed a named test, and every run's open audit counted no restricted open. The ledger takes the records, the runner, the test hashes and the replay steps, and the design note gets one sentence for the run. The comment's base64 block miscopies one character, at offset 5037. With that character restored, the block passes gzip's CRC check and matches the SHA-256 the comment gives for the file. The ledger's note records the repair. Co-Authored-By: Claude Opus 5.5 --- docs/design/track_b_insured_status.md | 3 + .../track_b_insured_status_mutations.json | 2988 ++++++++++++++++- 2 files changed, 2990 insertions(+), 1 deletion(-) diff --git a/docs/design/track_b_insured_status.md b/docs/design/track_b_insured_status.md index 82566d983..4a1f68e48 100644 --- a/docs/design/track_b_insured_status.md +++ b/docs/design/track_b_insured_status.md @@ -3926,6 +3926,9 @@ draws never reach the cap, and fails the boundary tests; `prior_basis_inverted` fails the shortcut's differential property. Round 24's list keeps round 23's and adds these 28; `precedence_possible` now drops only the `_refuse_unsupported_priors` call that round 24's checks follow. +A cloud session then ran all 135 at `d30e4426`, through every insured status +module. All 135 failed a named test, with no restricted open +(`round_24_mutations`, PR #562 comment 6620539979). With `f32d8812`'s `insured_status.py` in place of this round's, eight of the tests that call the rule fail: the UNKNOWN records of the unflagged prior, both diff --git a/docs/design/track_b_insured_status_mutations.json b/docs/design/track_b_insured_status_mutations.json index 94bbe9f54..e1fbea14d 100644 --- a/docs/design/track_b_insured_status_mutations.json +++ b/docs/design/track_b_insured_status_mutations.json @@ -13700,5 +13700,2991 @@ "tests/test_track_b_insured_status_fix_round_21.py": "dd858c630cbd0473745568cdcf92ac28b350bd4efe06e35f5be1f4c264b3aa04" }, "round_23_replay": "Write round_23_runner_source to scratch/review/run_round23_named.py. For each round_23_mutations record, write name/source_sha256/changes to its spec_path, then execute its exact command at f32d8812. Mutations apply only in memory.", - "round_23_final_source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab" + "round_23_final_source_sha256": "efe8608c9c388e8bd011c8e3be57e8c3c4f462520a37f9bf9fa697161245afab", + "round_24_mutations": [ + { + "changes": [ + { + "after": " chosen = vacant[:count]\n", + "before": " chosen = vacant[-count:] if year == at.year else vacant[:count]\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-worst_always_early.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/worst_always_early /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_either_bound_of_a_start_year_can_unseat_a_flagged_prior[counts2-3-None]" + ], + "log": "scratch/review/round24-mutation-worst_always_early.log", + "name": "worst_always_early", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-worst_always_early.json" + }, + { + "changes": [ + { + "after": " chosen = vacant[-count:]\n", + "before": " chosen = vacant[-count:] if year == at.year else vacant[:count]\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-worst_always_late.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/worst_always_late /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_placement_or_year_that_decides_the_basis_refuses" + ], + "log": "scratch/review/round24-mutation-worst_always_late.log", + "name": "worst_always_late", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-worst_always_late.json" + }, + { + "changes": [ + { + "after": " if _witness(\n person,\n lower,\n person.disability_onset,\n coverage_end_month,\n InsuredTest.DISABILITY,\n )[0]:\n lo_start = hi_start = person.disability_onset\n", + "before": " if _start_fixed(\n person,\n lower,\n person.disability_onset,\n month,\n coverage_end_month,\n ):\n lo_start = hi_start = person.disability_onset\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-start_on_favorable_placement.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/start_on_favorable_placement /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_status_on_every_placement_computes" + ], + "log": "scratch/review/round24-mutation-start_on_favorable_placement.log", + "name": "start_on_favorable_placement", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-start_on_favorable_placement.json" + }, + { + "changes": [ + { + "after": "", + "before": " if prior_unknown or current_unknown:\n _settle_every_history(\n person, lower, month, coverage_end_month, decisions, dli\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-no_universal_proof.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/no_universal_proof /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_date[known_end]" + ], + "log": "scratch/review/round24-mutation-no_universal_proof.log", + "name": "no_universal_proof", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-no_universal_proof.json" + }, + { + "changes": [ + { + "after": " if prior_unknown:\n _settle_every_history(", + "before": " if prior_unknown or current_unknown:\n _settle_every_history(" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-proof_skips_open_period.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/proof_skips_open_period /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_unknown_establishment_alone_refuses[InsuredTest.ALL]" + ], + "log": "scratch/review/round24-mutation-proof_skips_open_period.log", + "name": "proof_skips_open_period", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-proof_skips_open_period.json" + }, + { + "changes": [ + { + "after": " if current_unknown:\n _settle_every_history(", + "before": " if prior_unknown or current_unknown:\n _settle_every_history(" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-proof_skips_unknown_priors.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/proof_skips_unknown_priors /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_date[known_end]" + ], + "log": "scratch/review/round24-mutation-proof_skips_unknown_priors.log", + "name": "proof_skips_unknown_priors", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-proof_skips_unknown_priors.json" + }, + { + "changes": [ + { + "after": " _settle_every_history(\n person, upper, month,", + "before": " _settle_every_history(\n person, lower, month," + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-proof_on_upper_credits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/proof_on_upper_credits /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_date[unknown_year]" + ], + "log": "scratch/review/round24-mutation-proof_on_upper_credits.log", + "name": "proof_on_upper_credits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-proof_on_upper_credits.json" + }, + { + "changes": [ + { + "after": " if (\n decision is not None\n and False\n and not _every_placement_passes(\n", + "before": " if (\n decision is not None\n and decision.insured\n and not _every_placement_passes(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-proof_skips_statuses.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/proof_skips_statuses /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_status[first_day-InsuredTest.ALL]" + ], + "log": "scratch/review/round24-mutation-proof_skips_statuses.log", + "name": "proof_skips_statuses", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-proof_skips_statuses.json" + }, + { + "changes": [ + { + "after": " if (\n dli is not None\n and False\n and not _every_placement_passes(\n", + "before": " if (\n dli is not None\n and dli.lower is not None\n and not _every_placement_passes(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-proof_skips_the_date.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/proof_skips_the_date /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_can_undercut_the_date[known_end]" + ], + "log": "scratch/review/round24-mutation-proof_skips_the_date.log", + "name": "proof_skips_the_date", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-proof_skips_the_date.json" + }, + { + "changes": [ + { + "after": " month,\n", + "before": " decision.qualifying_quarter,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-status_tested_at_query.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/status_tested_at_query /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_status_stands_at_the_quarter_it_reports" + ], + "log": "scratch/review/round24-mutation-status_tested_at_query.log", + "name": "status_tested_at_query", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-status_tested_at_query.json" + }, + { + "changes": [ + { + "after": " month,\n", + "before": " _qdate(_qid(dli.lower)),\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-date_tested_at_query.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/date_tested_at_query /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_2.py::test_unknown_period_status_and_dli_bounds_contain_concrete_fillings" + ], + "log": "scratch/review/round24-mutation-date_tested_at_query.log", + "name": "date_tested_at_query", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-date_tested_at_query.json" + }, + { + "changes": [ + { + "after": " bare = person\n for kind, decision", + "before": " bare = replace(person, prior_disability_periods=())\n for kind, decision" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-proof_keeps_listed_priors.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/proof_keeps_listed_priors /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_unknown_establishment_needs_the_disregard" + ], + "log": "scratch/review/round24-mutation-proof_keeps_listed_priors.log", + "name": "proof_keeps_listed_priors", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-proof_keeps_listed_priors.json" + }, + { + "changes": [ + { + "after": " if False\n", + "before": " if blind is not None\n and not current_unknown\n and _prior_start_binds(\n person, lower, upper, index, month, coverage_end_month, blind\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-no_listed_prior_check.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/no_listed_prior_check /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_prior_basis_split_widens_the_qualifying_quarters" + ], + "log": "scratch/review/round24-mutation-no_listed_prior_check.log", + "name": "no_listed_prior_check", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-no_listed_prior_check.json" + }, + { + "changes": [ + { + "after": " if blind is not None\n and _prior_start_binds(\n person, lower, upper, index, month, coverage_end_month, blind\n )\n", + "before": " if blind is not None\n and not current_unknown\n and _prior_start_binds(\n person, lower, upper, index, month, coverage_end_month, blind\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-binding_reaches_open_period.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/binding_reaches_open_period /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_an_unknown_year_leaves_a_proven_result_to_the_proof" + ], + "log": "scratch/review/round24-mutation-binding_reaches_open_period.log", + "name": "binding_reaches_open_period", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-binding_reaches_open_period.json" + }, + { + "changes": [ + { + "after": " if False:\n", + "before": " if binding and unknown:\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-unknown_year_searches.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/unknown_year_searches /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_an_unknown_year_refuses" + ], + "log": "scratch/review/round24-mutation-unknown_year_searches.log", + "name": "unknown_year_searches", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-unknown_year_searches.json" + }, + { + "changes": [ + { + "after": " True\n or not (\n", + "before": " _prior_passes(\n person, filling, index, exit_month, blind=blind, **options\n )\n and not (\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-keeps_every_filling.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/keeps_every_filling /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_prior_basis_split_widens_the_qualifying_quarters" + ], + "log": "scratch/review/round24-mutation-keeps_every_filling.log", + "name": "keeps_every_filling", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-keeps_every_filling.json" + }, + { + "changes": [ + { + "after": "", + "before": " and not (\n person.prior_disability_periods[index].special_insured\n and _prior_passes(\n person,\n filling,\n index,\n exit_month,\n blind=False,\n ordinary_only=True,\n **options,\n )\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-keeps_ignores_the_flag.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/keeps_ignores_the_flag /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_flagged_prior_needs_paragraph_c_without_paragraph_b" + ], + "log": "scratch/review/round24-mutation-keeps_ignores_the_flag.log", + "name": "keeps_ignores_the_flag", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-keeps_ignores_the_flag.json" + }, + { + "changes": [ + { + "after": "", + "before": " if not _keeps_priors(person, filling, binding, exit_month):\n continue\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-start_search_ignores_priors.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/start_search_ignores_priors /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_split_start_names_the_listed_prior" + ], + "log": "scratch/review/round24-mutation-start_search_ignores_priors.log", + "name": "start_search_ignores_priors", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-start_search_ignores_priors.json" + }, + { + "changes": [ + { + "after": "", + "before": " if _keeps_priors(person, filling, binding, exit_month)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-listed_search_ignores_priors.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/listed_search_ignores_priors /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_prior_basis_split_widens_the_qualifying_quarters" + ], + "log": "scratch/review/round24-mutation-listed_search_ignores_priors.log", + "name": "listed_search_ignores_priors", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-listed_search_ignores_priors.json" + }, + { + "changes": [ + { + "after": " year\n for index, _ in ()\n", + "before": " year\n for index, _ in binding\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-no_prior_years.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/no_prior_years /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_either_bound_of_a_start_year_can_unseat_a_flagged_prior[counts2-3-None]" + ], + "log": "scratch/review/round24-mutation-no_prior_years.log", + "name": "no_prior_years", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-no_prior_years.json" + }, + { + "changes": [ + { + "after": " )\n", + "before": " ) | _prior_sensitive_years(person, binding)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-start_search_skips_prior_years.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/start_search_skips_prior_years /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_prior_reaches_a_year_the_start_cannot" + ], + "log": "scratch/review/round24-mutation-start_search_skips_prior_years.log", + "name": "start_search_skips_prior_years", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-start_search_skips_prior_years.json" + }, + { + "changes": [ + { + "after": " return settle(())\n", + "before": " return settle(binding)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-first_search_drops_binding.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/first_search_drops_binding /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_split_start_names_the_listed_prior" + ], + "log": "scratch/review/round24-mutation-first_search_drops_binding.log", + "name": "first_search_drops_binding", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-first_search_drops_binding.json" + }, + { + "changes": [ + { + "after": " for filling, completed in _fillings_keeping_start(\n person, credits, start, month, exit_month, favored, ()\n", + "before": " for filling, completed in _fillings_keeping_start(\n person, credits, start, month, exit_month, favored, binding\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-date_search_drops_binding.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/date_search_drops_binding /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_19.py::test_a_listed_prior_holds_every_ending_to_the_date" + ], + "log": "scratch/review/round24-mutation-date_search_drops_binding.log", + "name": "date_search_drops_binding", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-date_search_drops_binding.json" + }, + { + "changes": [ + { + "after": "", + "before": " *((InsuredTest.DISABILITY,) if binding else ()),\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-disability_left_out_of_search.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/disability_left_out_of_search /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_prior_basis_split_widens_the_qualifying_quarters" + ], + "log": "scratch/review/round24-mutation-disability_left_out_of_search.log", + "name": "disability_left_out_of_search", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-disability_left_out_of_search.json" + }, + { + "changes": [ + { + "after": " option,\n", + "before": " person if kind is InsuredTest.DISABILITY else option,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-disability_reads_the_completion.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/disability_reads_the_completion /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_period_begun_in_the_age_31_quarter_rests_on_paragraph_d" + ], + "log": "scratch/review/round24-mutation-disability_reads_the_completion.log", + "name": "disability_reads_the_completion", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-disability_reads_the_completion.json" + }, + { + "changes": [ + { + "after": " dated=False,\n last_insured=last_insured,\n reported=reported,\n detail=\"Annual placement decides", + "before": " dated=dated,\n last_insured=last_insured,\n reported=reported,\n detail=\"Annual placement decides" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-listed_search_skips_the_date.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/listed_search_skips_the_date /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_periods_still_may_not_share_a_day" + ], + "log": "scratch/review/round24-mutation-listed_search_skips_the_date.log", + "name": "listed_search_skips_the_date", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-listed_search_skips_the_date.json" + }, + { + "changes": [ + { + "after": " if not person.prior_disability_periods[index].special_insured:\n return True\n", + "before": " if not person.prior_disability_periods[index].special_insured:\n return not every\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-unflagged_refuses_every_placement.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/unflagged_refuses_every_placement /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_an_open_flag_keeps_paragraph_b_where_every_placement_meets_it" + ], + "log": "scratch/review/round24-mutation-unflagged_refuses_every_placement.log", + "name": "unflagged_refuses_every_placement", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-unflagged_refuses_every_placement.json" + }, + { + "changes": [ + { + "after": " True\n and not _every_placement_begins(\n", + "before": " _prior_passes(\n person, upper, index, exit_month, blind=False, **options\n )\n and not _every_placement_begins(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-flagged_ignores_support.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/flagged_ignores_support /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_either_bound_of_a_start_year_can_unseat_a_flagged_prior[counts4-None-outcome4]" + ], + "log": "scratch/review/round24-mutation-flagged_ignores_support.log", + "name": "flagged_ignores_support", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-flagged_ignores_support.json" + }, + { + "changes": [ + { + "after": "", + "before": " and not _every_placement_begins(\n person,\n lower,\n index,\n month,\n exit_month,\n blind=False,\n ordinary_only=True,\n **options,\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-flagged_ignores_ordinary_rule.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/flagged_ignores_ordinary_rule /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_flag_every_completion_contradicts_refuses_by_that_name[6]" + ], + "log": "scratch/review/round24-mutation-flagged_ignores_ordinary_rule.log", + "name": "flagged_ignores_ordinary_rule", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-flagged_ignores_ordinary_rule.json" + }, + { + "changes": [ + { + "after": " return True\n", + "before": " return not every or _prior_passes(\n person, upper, index, exit_month, blind=False, ordinary_only=True\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-flagged_refuses_every_placement.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/flagged_refuses_every_placement /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_an_ended_current_period_counts_as_the_prior_it_becomes" + ], + "log": "scratch/review/round24-mutation-flagged_refuses_every_placement.log", + "name": "flagged_refuses_every_placement", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-flagged_refuses_every_placement.json" + }, + { + "changes": [ + { + "after": " person, statutory_blindness=True, prior_disability_periods=()\n", + "before": " person, statutory_blindness=blind, prior_disability_periods=()\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-every_flagged_reads_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/every_flagged_reads_blindness /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_either_bound_of_a_start_year_can_unseat_a_flagged_prior[counts0-None-outcome0]" + ], + "log": "scratch/review/round24-mutation-every_flagged_reads_blindness.log", + "name": "every_flagged_reads_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-every_flagged_reads_blindness.json" + }, + { + "changes": [ + { + "after": " person, statutory_blindness=False, prior_disability_periods=()\n", + "before": " person, statutory_blindness=blind, prior_disability_periods=()\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-every_unflagged_reads_no_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/every_unflagged_reads_no_blindness /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_an_open_flag_keeps_paragraph_b_where_every_placement_meets_it" + ], + "log": "scratch/review/round24-mutation-every_unflagged_reads_no_blindness.log", + "name": "every_unflagged_reads_no_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-every_unflagged_reads_no_blindness.json" + }, + { + "changes": [ + { + "after": " statutory_blindness=True,\n prior_disability_periods=person.prior_disability_periods[:index],\n", + "before": " statutory_blindness=blind,\n prior_disability_periods=person.prior_disability_periods[:index],\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-route_flagged_reads_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/route_flagged_reads_blindness /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_either_bound_of_a_start_year_can_unseat_a_flagged_prior[counts0-None-outcome0]" + ], + "log": "scratch/review/round24-mutation-route_flagged_reads_blindness.log", + "name": "route_flagged_reads_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-route_flagged_reads_blindness.json" + }, + { + "changes": [ + { + "after": " statutory_blindness=False,\n prior_disability_periods=person.prior_disability_periods[:index],\n", + "before": " statutory_blindness=blind,\n prior_disability_periods=person.prior_disability_periods[:index],\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-route_unflagged_reads_no_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/route_unflagged_reads_no_blindness /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_a_year_that_can_leave_an_unflagged_prior_unsupported_refuses[2-None]" + ], + "log": "scratch/review/round24-mutation-route_unflagged_reads_no_blindness.log", + "name": "route_unflagged_reads_no_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-route_unflagged_reads_no_blindness.json" + }, + { + "changes": [ + { + "after": " person,\n statutory_blindness=blind,\n prior_disability_periods=person.prior_disability_periods[:index],\n", + "before": " person, statutory_blindness=blind, prior_disability_periods=()\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-every_reads_listed_periods.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/every_reads_listed_periods /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_a_later_prior_on_an_earlier_endpoint_binds" + ], + "log": "scratch/review/round24-mutation-every_reads_listed_periods.log", + "name": "every_reads_listed_periods", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-every_reads_listed_periods.json" + }, + { + "changes": [ + { + "after": " prior_disability_periods=(),\n )\n return _witness(\n", + "before": " prior_disability_periods=person.prior_disability_periods[:index],\n )\n return _witness(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-some_drops_earlier_periods.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/some_drops_earlier_periods /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_periods_still_may_not_share_a_day" + ], + "log": "scratch/review/round24-mutation-some_drops_earlier_periods.log", + "name": "some_drops_earlier_periods", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-some_drops_earlier_periods.json" + }, + { + "changes": [ + { + "after": " every = _every_placement_begins(\n person, upper, index, month, exit_month, blind=blind\n )\n", + "before": " every = _every_placement_begins(\n person, lower, index, month, exit_month, blind=blind\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-every_on_upper_credits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/every_on_upper_credits /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_an_unknown_year_can_support_a_prior" + ], + "log": "scratch/review/round24-mutation-every_on_upper_credits.log", + "name": "every_on_upper_credits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-every_on_upper_credits.json" + }, + { + "changes": [ + { + "after": " if _prior_passes(\n person, lower, index, exit_month, blind=blind, **options\n ):\n return blind\n", + "before": " if _prior_passes(\n person, upper, index, exit_month, blind=blind, **options\n ):\n return blind\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-some_on_lower_credits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/some_on_lower_credits /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_a_year_that_can_leave_an_unflagged_prior_unsupported_refuses[None-outcome0]" + ], + "log": "scratch/review/round24-mutation-some_on_lower_credits.log", + "name": "some_on_lower_credits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-some_on_lower_credits.json" + }, + { + "changes": [ + { + "after": " if (\n young and under31_route or subsequent and not young\n ):\n", + "before": " if not ordinary_only and (\n young and under31_route or subsequent and not young\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-ordinary_keeps_special_route.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/ordinary_keeps_special_route /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_either_bound_of_a_start_year_can_unseat_a_flagged_prior[counts0-None-outcome0]" + ], + "log": "scratch/review/round24-mutation-ordinary_keeps_special_route.log", + "name": "ordinary_keeps_special_route", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-ordinary_keeps_special_route.json" + }, + { + "changes": [ + { + "after": " person,\n person.disability_onset,\n _current_period_start_horizon(person, month),\n ) | _prior_sensitive_years(person, binding)\n", + "before": " person, person.disability_onset, start\n ) | _prior_sensitive_years(person, binding)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-fix_reverted.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/fix_reverted /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_partial_years_after_the_start_stay_open" + ], + "log": "scratch/review/round24-mutation-fix_reverted.log", + "name": "fix_reverted", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-fix_reverted.json" + }, + { + "changes": [ + { + "after": " for blind in (True,):\n", + "before": " for blind in (\n (False, True) if _blind_basis(person, index) else (False,)\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-basis_always_blind.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/basis_always_blind /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_a_quarter_after_the_start_can_exclude_the_pre1956_route[None]" + ], + "log": "scratch/review/round24-mutation-basis_always_blind.log", + "name": "basis_always_blind", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-basis_always_blind.json" + }, + { + "changes": [ + { + "after": " for blind in (False,):\n", + "before": " for blind in (\n (False, True) if _blind_basis(person, index) else (False,)\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-basis_always_nonblind.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/basis_always_nonblind /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_a_year_that_can_leave_an_unflagged_prior_unsupported_refuses[2-None]" + ], + "log": "scratch/review/round24-mutation-basis_always_nonblind.log", + "name": "basis_always_nonblind", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-basis_always_nonblind.json" + }, + { + "changes": [ + { + "after": " every = _every_placement_begins(\n person, lower, index, month, exit_month, blind=True\n )\n", + "before": " every = _every_placement_begins(\n person, lower, index, month, exit_month, blind=blind\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-binds_ignores_basis.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/binds_ignores_basis /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_prior_basis_split_widens_the_qualifying_quarters" + ], + "log": "scratch/review/round24-mutation-binds_ignores_basis.log", + "name": "binds_ignores_basis", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-binds_ignores_basis.json" + }, + { + "changes": [ + { + "after": " every = _every_placement_begins(\n person, lower, index, month, exit_month, blind=False\n )\n", + "before": " every = _every_placement_begins(\n person, lower, index, month, exit_month, blind=blind\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-binds_always_nonblind.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/binds_always_nonblind /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_an_open_flag_keeps_paragraph_b_where_every_placement_meets_it" + ], + "log": "scratch/review/round24-mutation-binds_always_nonblind.log", + "name": "binds_always_nonblind", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-binds_always_nonblind.json" + }, + { + "changes": [ + { + "after": " _prior_passes(\n person, filling, index, exit_month, blind=True, **options\n )\n and not (\n", + "before": " _prior_passes(\n person, filling, index, exit_month, blind=blind, **options\n )\n and not (\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-keeps_ignores_basis.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/keeps_ignores_basis /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_prior_basis_split_widens_the_qualifying_quarters" + ], + "log": "scratch/review/round24-mutation-keeps_ignores_basis.log", + "name": "keeps_ignores_basis", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-keeps_ignores_basis.json" + }, + { + "changes": [ + { + "after": " _prior_passes(\n person, filling, index, exit_month, blind=False, **options\n )\n and not (\n", + "before": " _prior_passes(\n person, filling, index, exit_month, blind=blind, **options\n )\n and not (\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-keeps_always_nonblind.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/keeps_always_nonblind /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_prior_basis_split_widens_the_qualifying_quarters" + ], + "log": "scratch/review/round24-mutation-keeps_always_nonblind.log", + "name": "keeps_always_nonblind", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-keeps_always_nonblind.json" + }, + { + "changes": [ + { + "after": " return True\n", + "before": " _refuse(\n InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY,\n \"No annual placement supports a listed prior's first insured quarter\",\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-no_support_stands.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/no_support_stands /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_a_year_that_can_leave_an_unflagged_prior_unsupported_refuses[None-outcome0]" + ], + "log": "scratch/review/round24-mutation-no_support_stands.log", + "name": "no_support_stands", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-no_support_stands.json" + }, + { + "changes": [ + { + "after": " _prior_passes(\n person, upper, index, exit_month, blind=True, **options\n )\n and not _every_placement_begins(\n", + "before": " _prior_passes(\n person, upper, index, exit_month, blind=False, **options\n )\n and not _every_placement_begins(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-flagged_support_reads_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/flagged_support_reads_blindness /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_either_bound_of_a_start_year_can_unseat_a_flagged_prior[counts4-None-outcome4]" + ], + "log": "scratch/review/round24-mutation-flagged_support_reads_blindness.log", + "name": "flagged_support_reads_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-flagged_support_reads_blindness.json" + }, + { + "changes": [ + { + "after": " and not _every_placement_begins(\n person,\n lower,\n index,\n month,\n exit_month,\n blind=True,\n ordinary_only=True,\n **options,\n )\n", + "before": " and not _every_placement_begins(\n person,\n lower,\n index,\n month,\n exit_month,\n blind=False,\n ordinary_only=True,\n **options,\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-flagged_ordinary_reads_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/flagged_ordinary_reads_blindness /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_either_bound_of_a_start_year_can_unseat_a_flagged_prior[counts0-None-outcome0]" + ], + "log": "scratch/review/round24-mutation-flagged_ordinary_reads_blindness.log", + "name": "flagged_ordinary_reads_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-flagged_ordinary_reads_blindness.json" + }, + { + "changes": [ + { + "after": " _prior_passes(\n person, lower, index, exit_month, blind=False, **options\n )\n and not _every_placement_begins(\n", + "before": " _prior_passes(\n person, upper, index, exit_month, blind=False, **options\n )\n and not _every_placement_begins(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-flagged_support_on_lower_credits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/flagged_support_on_lower_credits /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_either_bound_of_a_start_year_can_unseat_a_flagged_prior[counts4-None-outcome4]" + ], + "log": "scratch/review/round24-mutation-flagged_support_on_lower_credits.log", + "name": "flagged_support_on_lower_credits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-flagged_support_on_lower_credits.json" + }, + { + "changes": [ + { + "after": " and not _every_placement_begins(\n person,\n upper,\n index,\n month,\n exit_month,\n blind=False,\n ordinary_only=True,\n **options,\n )\n", + "before": " and not _every_placement_begins(\n person,\n lower,\n index,\n month,\n exit_month,\n blind=False,\n ordinary_only=True,\n **options,\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-flagged_ordinary_on_upper_credits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/flagged_ordinary_on_upper_credits /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_either_bound_of_a_start_year_can_unseat_a_flagged_prior[counts0-None-outcome0]" + ], + "log": "scratch/review/round24-mutation-flagged_ordinary_on_upper_credits.log", + "name": "flagged_ordinary_on_upper_credits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-flagged_ordinary_on_upper_credits.json" + }, + { + "changes": [ + { + "after": " bases = tuple(\n _prior_basis(person, lower, upper, index, month, coverage_end_month)\n for index in range(0 if current_unknown else len(person.prior_disability_periods))\n )\n", + "before": " bases = tuple(\n _prior_basis(person, lower, upper, index, month, coverage_end_month)\n for index in range(len(person.prior_disability_periods))\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-basis_skipped_on_open_period.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/basis_skipped_on_open_period /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_flagged_prior_needs_paragraph_c_without_paragraph_b" + ], + "log": "scratch/review/round24-mutation-basis_skipped_on_open_period.log", + "name": "basis_skipped_on_open_period", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-basis_skipped_on_open_period.json" + }, + { + "changes": [ + { + "after": " (index, True)\n for index, blind in enumerate(bases)\n", + "before": " (index, blind)\n for index, blind in enumerate(bases)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-binding_pair_drops_basis.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/binding_pair_drops_basis /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_prior_basis_split_widens_the_qualifying_quarters" + ], + "log": "scratch/review/round24-mutation-binding_pair_drops_basis.log", + "name": "binding_pair_drops_basis", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-binding_pair_drops_basis.json" + }, + { + "changes": [ + { + "after": " bases = tuple(\n _prior_basis(person, lower, upper, index, month, coverage_end_month)\n for index in range(len(person.prior_disability_periods) if test in (InsuredTest.ALL, InsuredTest.DISABILITY) else 0)\n )\n", + "before": " bases = tuple(\n _prior_basis(person, lower, upper, index, month, coverage_end_month)\n for index in range(len(person.prior_disability_periods))\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-basis_only_on_disability.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/basis_only_on_disability /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_only_a_middle_completion_fits_a_flag[None-InsuredTest.FULLY-InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY-Annual" + ], + "log": "scratch/review/round24-mutation-basis_only_on_disability.log", + "name": "basis_only_on_disability", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-basis_only_on_disability.json" + }, + { + "changes": [ + { + "after": " return not every or _prior_passes(\n person, upper, index, exit_month, blind=True, ordinary_only=True\n )\n", + "before": " return not every or _prior_passes(\n person, upper, index, exit_month, blind=False, ordinary_only=True\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-binds_flag_reads_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/binds_flag_reads_blindness /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_20.py::test_an_unknown_year_leaves_a_special_prior_every_placement_carries" + ], + "log": "scratch/review/round24-mutation-binds_flag_reads_blindness.log", + "name": "binds_flag_reads_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-binds_flag_reads_blindness.json" + }, + { + "changes": [ + { + "after": " return not every or _prior_passes(\n person, lower, index, exit_month, blind=False, ordinary_only=True\n )\n", + "before": " return not every or _prior_passes(\n person, upper, index, exit_month, blind=False, ordinary_only=True\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-binds_flag_on_lower_credits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/binds_flag_on_lower_credits /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_an_unknown_year_can_carry_a_flagged_prior_past_the_ordinary_rule" + ], + "log": "scratch/review/round24-mutation-binds_flag_on_lower_credits.log", + "name": "binds_flag_on_lower_credits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-binds_flag_on_lower_credits.json" + }, + { + "changes": [ + { + "after": " and not (\n person.prior_disability_periods[index].special_insured\n and _prior_passes(\n person,\n filling,\n index,\n exit_month,\n blind=True,\n ordinary_only=True,\n **options,\n )\n )\n", + "before": " and not (\n person.prior_disability_periods[index].special_insured\n and _prior_passes(\n person,\n filling,\n index,\n exit_month,\n blind=False,\n ordinary_only=True,\n **options,\n )\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-keeps_flag_reads_blindness.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/keeps_flag_reads_blindness /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_either_bound_of_a_start_year_can_unseat_a_flagged_prior[counts0-None-outcome0]" + ], + "log": "scratch/review/round24-mutation-keeps_flag_reads_blindness.log", + "name": "keeps_flag_reads_blindness", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-keeps_flag_reads_blindness.json" + }, + { + "changes": [ + { + "after": " if binding:\n favored_rows, _ = _world(", + "before": " if lo_start is not None or binding:\n favored_rows, _ = _world(" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-remove_first_start_check.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/remove_first_start_check /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[109307]" + ], + "log": "scratch/review/round24-mutation-remove_first_start_check.log", + "name": "remove_first_start_check", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-remove_first_start_check.json" + }, + { + "changes": [ + { + "after": " if False and any(\n _improves(outcome, returned, last_insured)\n for outcome in _period_outcomes(", + "before": " if any(\n _improves(outcome, returned, last_insured)\n for outcome in _period_outcomes(" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-drop_bound_refusal.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/drop_bound_refusal /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[109307]" + ], + "log": "scratch/review/round24-mutation-drop_bound_refusal.log", + "name": "drop_bound_refusal", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-drop_bound_refusal.json" + }, + { + "changes": [ + { + "after": " \"dated\": False,\n \"last_insured\": None,\n", + "before": " \"dated\": dli is not None,\n \"last_insured\": dli.upper if dli is not None else None,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-drop_dli_comparison.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/drop_dli_comparison /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_frozen_exit_refuses" + ], + "log": "scratch/review/round24-mutation-drop_dli_comparison.log", + "name": "drop_dli_comparison", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-drop_dli_comparison.json" + }, + { + "changes": [ + { + "after": " return _every_placement_passes(\n person, credits, start, month, exit_month, InsuredTest.DISABILITY\n )", + "before": " return not person.prior_disability_periods and _every_placement_passes(\n person, credits, start, month, exit_month, InsuredTest.DISABILITY\n )" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-start_fixed_ignores_priors.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/start_fixed_ignores_priors /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_current_period_after_that_prior_refuses" + ], + "log": "scratch/review/round24-mutation-start_fixed_ignores_priors.log", + "name": "start_fixed_ignores_priors", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-start_fixed_ignores_priors.json" + }, + { + "changes": [ + { + "after": " horizon = _current_period_start_horizon(person, month)\n for quarter in range(_qid(start), _qid(start) + 1):\n try:\n completed, own_start = _complete_current_period(", + "before": " horizon = _current_period_start_horizon(person, month)\n for quarter in range(_qid(start), _qid(horizon) + 1):\n try:\n completed, own_start = _complete_current_period(" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-bound_stops_at_reported_start.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/bound_stops_at_reported_start /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_status_stress.py::test_status_stress_refuses_a_start_no_filling_supports[109307]" + ], + "log": "scratch/review/round24-mutation-bound_stops_at_reported_start.log", + "name": "bound_stops_at_reported_start", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-bound_stops_at_reported_start.json" + }, + { + "changes": [ + { + "after": " if not ordinary_only and (\n young or subsequent and not young\n ):\n", + "before": " if not ordinary_only and (\n young and under31_route or subsequent and not young\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-unflagged_reads_paragraph_c.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/unflagged_reads_paragraph_c /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_prior_basis_split_widens_the_qualifying_quarters" + ], + "log": "scratch/review/round24-mutation-unflagged_reads_paragraph_c.log", + "name": "unflagged_reads_paragraph_c", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-unflagged_reads_paragraph_c.json" + }, + { + "changes": [ + { + "after": " if not ordinary_only and (\n young and under31_route or subsequent\n ):\n", + "before": " if not ordinary_only and (\n young and under31_route or subsequent and not young\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-young_takes_subsequent_route.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/young_takes_subsequent_route /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_young_prior_after_a_flagged_one_rests_on_paragraph_b" + ], + "log": "scratch/review/round24-mutation-young_takes_subsequent_route.log", + "name": "young_takes_subsequent_route", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-young_takes_subsequent_route.json" + }, + { + "changes": [ + { + "after": " if not ordinary_only and (\n under31_route and (young or subsequent)\n ):\n", + "before": " if not ordinary_only and (\n young and under31_route or subsequent and not young\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-unflagged_drops_paragraph_d.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/unflagged_drops_paragraph_d /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_22.py::test_a_prior_past_31_after_a_flagged_one_can_rest_on_paragraph_d" + ], + "log": "scratch/review/round24-mutation-unflagged_drops_paragraph_d.log", + "name": "unflagged_drops_paragraph_d", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-unflagged_drops_paragraph_d.json" + }, + { + "changes": [ + { + "after": " InsuredTest.DISABILITY,\n under31_route=True,\n **options,\n )[0]\n", + "before": " InsuredTest.DISABILITY,\n under31_route=period.special_insured,\n **options,\n )[0]\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-route_reads_paragraph_c.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/route_reads_paragraph_c /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_an_open_flag_keeps_paragraph_b_where_every_placement_meets_it" + ], + "log": "scratch/review/round24-mutation-route_reads_paragraph_c.log", + "name": "route_reads_paragraph_c", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-route_reads_paragraph_c.json" + }, + { + "changes": [ + { + "after": " InsuredTest.DISABILITY,\n under31_route=True,\n **options,\n )\n\n", + "before": " InsuredTest.DISABILITY,\n under31_route=period.special_insured,\n **options,\n )\n\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-every_reads_paragraph_c.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/every_reads_paragraph_c /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_prior_basis_split_widens_the_qualifying_quarters" + ], + "log": "scratch/review/round24-mutation-every_reads_paragraph_c.log", + "name": "every_reads_paragraph_c", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-every_reads_paragraph_c.json" + }, + { + "changes": [ + { + "after": " InsuredTest.DISABILITY,\n under31_route=False,\n **options,\n )[0]\n", + "before": " InsuredTest.DISABILITY,\n under31_route=period.special_insured,\n **options,\n )[0]\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-route_drops_flagged_paragraph_c.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/route_drops_flagged_paragraph_c /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_either_bound_of_a_start_year_can_unseat_a_flagged_prior[counts0-None-outcome0]" + ], + "log": "scratch/review/round24-mutation-route_drops_flagged_paragraph_c.log", + "name": "route_drops_flagged_paragraph_c", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-route_drops_flagged_paragraph_c.json" + }, + { + "changes": [ + { + "after": " InsuredTest.DISABILITY,\n under31_route=False,\n **options,\n )\n\n", + "before": " InsuredTest.DISABILITY,\n under31_route=period.special_insured,\n **options,\n )\n\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-every_drops_flagged_paragraph_c.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/every_drops_flagged_paragraph_c /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_21.py::test_an_unknown_year_can_carry_a_flagged_prior_past_the_ordinary_rule" + ], + "log": "scratch/review/round24-mutation-every_drops_flagged_paragraph_c.log", + "name": "every_drops_flagged_paragraph_c", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-every_drops_flagged_paragraph_c.json" + }, + { + "changes": [ + { + "after": " ordinary_only=False,\n under31_route=False,\n):\n", + "before": " ordinary_only=False,\n under31_route=True,\n):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-current_drops_paragraph_c.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/current_drops_paragraph_c /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_period_begun_on_paragraph_c_alone_opens_paragraph_d_after_it" + ], + "log": "scratch/review/round24-mutation-current_drops_paragraph_c.log", + "name": "current_drops_paragraph_c", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-current_drops_paragraph_c.json" + }, + { + "changes": [ + { + "after": " return _complete_current_period(person, quarter, special=False)\n", + "before": " return _complete_current_period(person, quarter, special=special is True)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-m1_flag.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/m1_flag /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_period_begun_on_paragraph_c_alone_opens_paragraph_d_after_it" + ], + "log": "scratch/review/round24-mutation-m1_flag.log", + "name": "m1_flag", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-m1_flag.json" + }, + { + "changes": [ + { + "after": " if i and _qid(period.start) <= _qid(periods[i - 1].end):\n", + "before": " if i and period.start <= periods[i - 1].end:\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-m2_listed.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/m2_listed /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_rs00301_140_example_7_begins_on_the_onset_day" + ], + "log": "scratch/review/round24-mutation-m2_listed.log", + "name": "m2_listed", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-m2_listed.json" + }, + { + "changes": [ + { + "after": " and _qid(period.end) >= _qid(person.disability_onset)\n", + "before": " and period.end >= person.disability_onset\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-m2_current.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/m2_current /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_rs00301_140_example_7_begins_on_the_onset_day" + ], + "log": "scratch/review/round24-mutation-m2_current.log", + "name": "m2_current", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-m2_current.json" + }, + { + "changes": [ + { + "after": " through_quarter=min(qid, _qid(exit_month)) if exit_month else qid,\n", + "before": " through_quarter=qid,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-m3_exit.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/m3_exit /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_an_open_flag_keeps_paragraph_b_where_every_placement_meets_it" + ], + "log": "scratch/review/round24-mutation-m3_exit.log", + "name": "m3_exit", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-m3_exit.json" + }, + { + "changes": [ + { + "after": " allowed = tuple(q for q in allowed if q >= _qid(person.birth_date))\n rows[year] = (fixed, flexible, allowed)\n return rows, periods\n", + "before": " rows[year] = (fixed, flexible, allowed)\n return rows, periods\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-m13_birth.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/m13_birth /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_birth_year_credits_quarters_before_the_birth" + ], + "log": "scratch/review/round24-mutation-m13_birth.log", + "name": "m13_birth", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-m13_birth.json" + }, + { + "changes": [ + { + "after": " first = 0\n", + "before": " first = -_qid(quarter) if disability and witness[0] else 0\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-m4_rank.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/m4_rank /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_binding_prior_keeps_the_earliest_qualifying_quarter" + ], + "log": "scratch/review/round24-mutation-m4_rank.log", + "name": "m4_rank", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-m4_rank.json" + }, + { + "changes": [ + { + "after": " maximum_qcs if broad else None,\n earliest=None,\n", + "before": " maximum_qcs if broad else None,\n earliest=earliest,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-m5_earliest.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/m5_earliest /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_unknown_priors_reach_the_onset_quarter" + ], + "log": "scratch/review/round24-mutation-m5_earliest.log", + "name": "m5_earliest", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-m5_earliest.json" + }, + { + "changes": [ + { + "after": " if False\n and not for_disability\n", + "before": " if living\n and not for_disability\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-m6_men.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/m6_men /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_the_404_115_table_gives_each_cohort_its_count" + ], + "log": "scratch/review/round24-mutation-m6_men.log", + "name": "m6_men", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-m6_men.json" + }, + { + "changes": [ + { + "after": " ):\n return False\n", + "before": " and _flag_fits(\n person, lower, upper, index, month, exit_month, **options\n )\n ):\n return False\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-m7_flagfits.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/m7_flagfits /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_flagged_prior_needs_paragraph_c_without_paragraph_b" + ], + "log": "scratch/review/round24-mutation-m7_flagfits.log", + "name": "m7_flagfits", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-m7_flagfits.json" + }, + { + "changes": [ + { + "after": " try:\n _refuse_undecided_priors(\n", + "before": " try:\n _refuse_unsupported_priors(\n person, lower, upper, month, coverage_end_month\n )\n _refuse_undecided_priors(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-precedence_possible.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/precedence_possible /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_a_year_that_can_leave_an_unflagged_prior_unsupported_refuses[0-outcome1]" + ], + "log": "scratch/review/round24-mutation-precedence_possible.log", + "name": "precedence_possible", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-precedence_possible.json" + }, + { + "changes": [ + { + "after": " if unknown:\n", + "before": " if unknown:\n _refuse_unsupported_priors(\n person, lower, upper, month, coverage_end_month\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-precedence_unknown.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/precedence_unknown /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_an_unsupported_prior_refuses_before_unknown_earnings[None]" + ], + "log": "scratch/review/round24-mutation-precedence_unknown.log", + "name": "precedence_unknown", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-precedence_unknown.json" + }, + { + "changes": [ + { + "after": " counts = [(lower[y][1], upper[y][1]) for y in open_years]\n", + "before": " counts = [range(lower[y][1], upper[y][1] + 1) for y in open_years]\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-flag_middle.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/flag_middle /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_only_a_middle_completion_fits_a_flag[None-InsuredTest.FULLY-InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY-Annual" + ], + "log": "scratch/review/round24-mutation-flag_middle.log", + "name": "flag_middle", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-flag_middle.json" + }, + { + "changes": [ + { + "after": " 1960 * 4 + 2,\n", + "before": " min(_qid(covered), 1960 * 4 + 2),\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-pre1956_scan.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/pre1956_scan /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_a_quarter_after_the_start_can_exclude_the_pre1956_route[flags5]" + ], + "log": "scratch/review/round24-mutation-pre1956_scan.log", + "name": "pre1956_scan", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-pre1956_scan.json" + }, + { + "changes": [ + { + "after": " ):\n pass\n _refuse(\n InsuredUnsupportedReason.DISABILITY_BEFORE_1956,\n", + "before": " ):\n return None\n _refuse(\n InsuredUnsupportedReason.DISABILITY_BEFORE_1956,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-pre1956_none.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/pre1956_none /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_a_quarter_after_the_start_can_exclude_the_pre1956_route[flags1]" + ], + "log": "scratch/review/round24-mutation-pre1956_none.log", + "name": "pre1956_none", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-pre1956_none.json" + }, + { + "changes": [ + { + "after": " raise error from None\n _refuse(\n InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY,\n \"First insured start depends on annual placement or prior treatment\",\n", + "before": " raise error from None\n _refuse(\n InsuredUnsupportedReason.ASSIGNMENT_COMPLEXITY,\n \"Annual placement decides a listed prior's first insured quarter\",\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-nit29.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/nit29 /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_split_start_names_the_listed_prior" + ], + "log": "scratch/review/round24-mutation-nit29.log", + "name": "nit29", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-nit29.json" + }, + { + "changes": [ + { + "after": " and self.current_disability_period_end > fra_end + timedelta(days=9999)\n", + "before": " and self.current_disability_period_end > fra_end\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-low12.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/low12 /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_declared_dates_past_the_statutory_end_are_input_errors" + ], + "log": "scratch/review/round24-mutation-low12.log", + "name": "low12", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-low12.json" + }, + { + "changes": [ + { + "after": " and self.dib_entitlement_month > fra.replace(day=1)\n", + "before": " and self.dib_entitlement_month >= fra.replace(day=1)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-low16_dib.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/low16_dib /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_entitlement_months_must_be_possible[dib_entitlement_month-month1-at" + ], + "log": "scratch/review/round24-mutation-low16_dib.log", + "name": "low16_dib", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-low16_dib.json" + }, + { + "changes": [ + { + "after": " < _attain(self.birth_date, 62).replace(day=1) - timedelta(days=31)\n", + "before": " < _attain(self.birth_date, 62).replace(day=1)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-low16_rib.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/low16_rib /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_entitlement_months_must_be_possible[rib_entitlement_month-month4-before" + ], + "log": "scratch/review/round24-mutation-low16_rib.log", + "name": "low16_rib", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-low16_rib.json" + }, + { + "changes": [ + { + "after": " and True\n", + "before": " and _qdate(_qid(_attain(person.birth_date, 31))) < date(1983, 5, 1)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-low19.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/low19 /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_the_pre_1983_refusal_needs_31_before_may_1983" + ], + "log": "scratch/review/round24-mutation-low19.log", + "name": "low19", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-low19.json" + }, + { + "changes": [ + { + "after": " It runs the person and query checks ``insured_status`` runs.\n \"\"\"\n", + "before": " It runs the person and query checks ``insured_status`` runs.\n \"\"\"\n _validate_person_at(person, month)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-low23.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/low23 /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_the_requirement_helper_checks_what_insured_status_checks" + ], + "log": "scratch/review/round24-mutation-low23.log", + "name": "low23", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-low23.json" + }, + { + "changes": [ + { + "after": " (row.quarterly_wages, cutoff, \"Quarterly earnings\"),\n", + "before": " (row.quarterly_wages, paid, \"Quarterly earnings\"),\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-low24.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/low24 /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_wages_paid_after_death_count_toward_the_year" + ], + "log": "scratch/review/round24-mutation-low24.log", + "name": "low24", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-low24.json" + }, + { + "changes": [ + { + "after": " raise InvalidFamilyInput(f\"{label} declared after coverage ends\")\n", + "before": " raise InvalidFamilyInput(f\"{label} declared before birth\")\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-nit25.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/nit25 /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_quarterly_bounds_name_themselves[1960-declared0-QCs" + ], + "log": "scratch/review/round24-mutation-nit25.log", + "name": "nit25", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-nit25.json" + }, + { + "changes": [ + { + "after": " return not period.special_insured\n", + "before": " return not period.special_insured and period.start >= date(1973, 1, 1)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-low21.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/low21 /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_a_quarter_after_the_start_can_exclude_the_pre1956_route[None]" + ], + "log": "scratch/review/round24-mutation-low21.log", + "name": "low21", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-low21.json" + }, + { + "changes": [ + { + "after": " if False:\n _settle_current_basis(\n", + "before": " if lo_start is not None and not prior_unknown:\n _settle_current_basis(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-m1_settle.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/m1_settle /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_placement_or_year_that_decides_the_basis_refuses" + ], + "log": "scratch/review/round24-mutation-m1_settle.log", + "name": "m1_settle", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-m1_settle.json" + }, + { + "changes": [ + { + "after": " ordinary_only=True,\n ):\n return False\n return False\n", + "before": " ordinary_only=True,\n ):\n return False\n return None\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-m1_open_basis.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/m1_open_basis /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_placement_or_year_that_decides_the_basis_refuses" + ], + "log": "scratch/review/round24-mutation-m1_open_basis.log", + "name": "m1_open_basis", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-m1_open_basis.json" + }, + { + "changes": [ + { + "after": " )\n if len(elapsed) < 15:\n window, required = (\n _window(end, 12, periods, boundary),\n", + "before": " )\n if len(elapsed) < 12:\n window, required = (\n _window(end, 12, periods, boundary),\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-first_onset_short.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/first_onset_short /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_each_published_first_onset_reproduces[rs140-joseph-6]" + ], + "log": "scratch/review/round24-mutation-first_onset_short.log", + "name": "first_onset_short", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-first_onset_short.json" + }, + { + "changes": [ + { + "after": " else:\n window, required = elapsed, max(6, (len(elapsed) + 1) // 2)\n candidates.append(\n", + "before": " else:\n window, required = elapsed, max(6, len(elapsed) // 2)\n candidates.append(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-first_onset_odd.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/first_onset_odd /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_period_begun_on_paragraph_c_alone_opens_paragraph_d_after_it" + ], + "log": "scratch/review/round24-mutation-first_onset_odd.log", + "name": "first_onset_odd", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-first_onset_odd.json" + }, + { + "changes": [ + { + "after": " (\"prior_disability_period_basis\", False),\n", + "before": " (\"prior_disability_period_basis\", basis_split),\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-basis_split_unreported.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/basis_split_unreported /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_prior_basis_split_widens_the_qualifying_quarters" + ], + "log": "scratch/review/round24-mutation-basis_split_unreported.log", + "name": "basis_split_unreported", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-basis_split_unreported.json" + }, + { + "changes": [ + { + "after": " (\"prior_disability_period_basis\", True),\n", + "before": " (\"prior_disability_period_basis\", basis_split),\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-basis_split_always.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/basis_split_always /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_binding_prior_keeps_the_earliest_qualifying_quarter" + ], + "log": "scratch/review/round24-mutation-basis_split_always.log", + "name": "basis_split_always", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-basis_split_always.json" + }, + { + "changes": [ + { + "after": " living = person.death_date is None\n", + "before": " living = person.death_date is None or person.death_date > at\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-m4_living.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/m4_living /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_death_after_the_query_keeps_the_living_count" + ], + "log": "scratch/review/round24-mutation-m4_living.log", + "name": "m4_living", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-m4_living.json" + }, + { + "changes": [ + { + "after": " if person.statutory_blindness or _qid(quarter) > _qid(\n", + "before": " if person.statutory_blindness or _qid(quarter) >= _qid(\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-m8_age31.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/m8_age31 /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_period_begun_in_the_age_31_quarter_rests_on_paragraph_d" + ], + "log": "scratch/review/round24-mutation-m8_age31.log", + "name": "m8_age31", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-m8_age31.json" + }, + { + "changes": [ + { + "after": " if period.end > fra_end + timedelta(days=9999):\n # The same 404.321 end binds a listed prior.\n", + "before": " if period.end > fra_end:\n # The same 404.321 end binds a listed prior.\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-low12_prior.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/low12_prior /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_declared_dates_past_the_statutory_end_are_input_errors" + ], + "log": "scratch/review/round24-mutation-low12_prior.log", + "name": "low12_prior", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-low12_prior.json" + }, + { + "changes": [ + { + "after": "return _complete_current_period(person, quarter, special=special is not False)", + "before": "return _complete_current_period(person, quarter, special=special is True)" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-open_flag_as_special.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/open_flag_as_special /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_an_open_flag_keeps_paragraph_b_where_every_placement_meets_it" + ], + "log": "scratch/review/round24-mutation-open_flag_as_special.log", + "name": "open_flag_as_special", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-open_flag_as_special.json" + }, + { + "changes": [ + { + "after": " if len(found) == 1:\n", + "before": " if len(found) == 1 and None not in found:\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-settle_accepts_open_flag.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/settle_accepts_open_flag /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_placement_or_year_that_decides_the_basis_refuses" + ], + "log": "scratch/review/round24-mutation-settle_accepts_open_flag.log", + "name": "settle_accepts_open_flag", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-settle_accepts_open_flag.json" + }, + { + "changes": [ + { + "after": "return not period.special_insured and period.start >= date(1972, 1, 1)", + "before": "return not period.special_insured and period.start >= date(1973, 1, 1)" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-blind_basis_1972.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/blind_basis_1972 /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_past_blindness_begins_a_prior_only_from_1973[start0-False]" + ], + "log": "scratch/review/round24-mutation-blind_basis_1972.log", + "name": "blind_basis_1972", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-blind_basis_1972.json" + }, + { + "changes": [ + { + "after": " if False:\n", + "before": " if earliest is not None and hi[0]:\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-no_earliest_widening.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/no_earliest_widening /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_unknown_priors_reach_the_onset_quarter" + ], + "log": "scratch/review/round24-mutation-no_earliest_widening.log", + "name": "no_earliest_widening", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-no_earliest_widening.json" + }, + { + "changes": [ + { + "after": " return True\n return True\n binding = ((index, False),)\n sensitive = _prior_sensitive_years(person, binding)\n", + "before": " return True\n binding = ((index, False),)\n sensitive = _prior_sensitive_years(person, binding)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-flag_fits_always.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/flag_fits_always /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_23.py::test_a_flagged_prior_needs_paragraph_c_without_paragraph_b" + ], + "log": "scratch/review/round24-mutation-flag_fits_always.log", + "name": "flag_fits_always", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-flag_fits_always.json" + }, + { + "changes": [ + { + "after": " return\n flagged = bool(person.conditions & _FULLY_INSURED_ROUTE_CONDITIONS)\n for index, period in enumerate(person.prior_disability_periods):\n", + "before": " flagged = bool(person.conditions & _FULLY_INSURED_ROUTE_CONDITIONS)\n for index, period in enumerate(person.prior_disability_periods):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-undecided_off.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/undecided_off /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_a_year_that_can_leave_an_unflagged_prior_unsupported_refuses[None-outcome0]" + ], + "log": "scratch/review/round24-mutation-undecided_off.log", + "name": "undecided_off", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-undecided_off.json" + }, + { + "changes": [ + { + "after": "", + "before": " _refuse_undecided_priors(\n person, lower, upper, month, coverage_end_month\n )\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-undecided_call_dropped.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/undecided_call_dropped /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_a_year_that_can_leave_an_unflagged_prior_unsupported_refuses[None-outcome0]" + ], + "log": "scratch/review/round24-mutation-undecided_call_dropped.log", + "name": "undecided_call_dropped", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-undecided_call_dropped.json" + }, + { + "changes": [ + { + "after": " if date(1952, 7, 1) <= period.start < date(1956, 1, 1):\n", + "before": " if period.special_insured or (\n date(1952, 7, 1) <= period.start < date(1956, 1, 1)\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-scan_flagged_on_lower.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/scan_flagged_on_lower /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_either_bound_of_a_start_year_can_unseat_a_flagged_prior[counts0-None-outcome0]" + ], + "log": "scratch/review/round24-mutation-scan_flagged_on_lower.log", + "name": "scan_flagged_on_lower", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-scan_flagged_on_lower.json" + }, + { + "changes": [ + { + "after": " if period.special_insured:\n", + "before": " if period.special_insured or (\n date(1952, 7, 1) <= period.start < date(1956, 1, 1)\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-scan_pre1956_on_lower.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/scan_pre1956_on_lower /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_a_quarter_after_the_start_can_exclude_the_pre1956_route[None]" + ], + "log": "scratch/review/round24-mutation-scan_pre1956_on_lower.log", + "name": "scan_pre1956_on_lower", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-scan_pre1956_on_lower.json" + }, + { + "changes": [ + { + "after": " if True:\n", + "before": " if period.special_insured or (\n date(1952, 7, 1) <= period.start < date(1956, 1, 1)\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-scan_every_prior.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/scan_every_prior /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_a_prior_before_july_1952_rests_on_lower_credits" + ], + "log": "scratch/review/round24-mutation-scan_every_prior.log", + "name": "scan_every_prior", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-scan_every_prior.json" + }, + { + "changes": [ + { + "after": " if period.special_insured or period.start < date(1956, 1, 1):\n", + "before": " if period.special_insured or (\n date(1952, 7, 1) <= period.start < date(1956, 1, 1)\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-scan_window_from_1937.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/scan_window_from_1937 /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_a_prior_before_july_1952_rests_on_lower_credits" + ], + "log": "scratch/review/round24-mutation-scan_window_from_1937.log", + "name": "scan_window_from_1937", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-scan_window_from_1937.json" + }, + { + "changes": [ + { + "after": " completions = _completions(\n lower, upper, max(period.start.year, 1960)\n )\n", + "before": " completions = _completions(lower, upper, period.start.year)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-scan_to_1960.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/scan_to_1960 /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_years_after_a_pre1956_start_count_at_their_upper_credits" + ], + "log": "scratch/review/round24-mutation-scan_to_1960.log", + "name": "scan_to_1960", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-scan_to_1960.json" + }, + { + "changes": [ + { + "after": " completions = _completions(lower, upper, period.start.year - 1)\n", + "before": " completions = _completions(lower, upper, period.start.year)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-scan_before_start_year.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/scan_before_start_year /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_either_bound_of_a_start_year_can_unseat_a_flagged_prior[counts4-None-outcome4]" + ], + "log": "scratch/review/round24-mutation-scan_before_start_year.log", + "name": "scan_before_start_year", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-scan_before_start_year.json" + }, + { + "changes": [ + { + "after": " else:\n completions = (upper,)\n", + "before": " else:\n completions = (lower,)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-unflagged_on_upper.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/unflagged_on_upper /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_a_year_that_can_leave_an_unflagged_prior_unsupported_refuses[None-outcome0]" + ], + "log": "scratch/review/round24-mutation-unflagged_on_upper.log", + "name": "unflagged_on_upper", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-unflagged_on_upper.json" + }, + { + "changes": [ + { + "after": " if True:\n", + "before": " if not (\n flagged\n and _flag_carries_prior(\n person, credits, credits, index, month, exit_month\n )\n ):\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-rescue_dropped.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/rescue_dropped /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_a_flag_that_carries_the_prior_keeps_the_input_error[None]" + ], + "log": "scratch/review/round24-mutation-rescue_dropped.log", + "name": "rescue_dropped", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-rescue_dropped.json" + }, + { + "changes": [ + { + "after": " if True:\n options.append([(fixed, count) for count in range(low, high + 1)])\n", + "before": " if year >= 1978:\n options.append([(fixed, count) for count in range(low, high + 1)])\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-completions_counts_only.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/completions_counts_only /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_a_quarter_after_the_start_can_exclude_the_pre1956_route[None]" + ], + "log": "scratch/review/round24-mutation-completions_counts_only.log", + "name": "completions_counts_only", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-completions_counts_only.json" + }, + { + "changes": [ + { + "after": " if year > 1978:\n options.append([(fixed, count) for count in range(low, high + 1)])\n", + "before": " if year >= 1978:\n options.append([(fixed, count) for count in range(low, high + 1)])\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-completions_sets_from_1979.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/completions_sets_from_1979 /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_completions_list_quarter_sets_before_1978_and_counts_after" + ], + "log": "scratch/review/round24-mutation-completions_sets_from_1979.log", + "name": "completions_sets_from_1979", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-completions_sets_from_1979.json" + }, + { + "changes": [ + { + "after": " years = [y for y in upper if y < last and lower[y] != upper[y]]\n", + "before": " years = [y for y in upper if y <= last and lower[y] != upper[y]]\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-completions_last_exclusive.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/completions_last_exclusive /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_either_bound_of_a_start_year_can_unseat_a_flagged_prior[counts4-None-outcome4]" + ], + "log": "scratch/review/round24-mutation-completions_last_exclusive.log", + "name": "completions_last_exclusive", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-completions_last_exclusive.json" + }, + { + "changes": [ + { + "after": " for size in range(low, high)\n", + "before": " for size in range(low, high + 1)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-completions_sets_short.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/completions_sets_short /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_completions_list_quarter_sets_before_1978_and_counts_after" + ], + "log": "scratch/review/round24-mutation-completions_sets_short.log", + "name": "completions_sets_short", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-completions_sets_short.json" + }, + { + "changes": [ + { + "after": " options.append([(fixed, count) for count in range(low, high)])\n", + "before": " options.append([(fixed, count) for count in range(low, high + 1)])\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-completions_counts_short.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/completions_counts_short /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_either_bound_of_a_start_year_can_unseat_a_flagged_prior[counts0-None-outcome0]" + ], + "log": "scratch/review/round24-mutation-completions_counts_short.log", + "name": "completions_counts_short", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-completions_counts_short.json" + }, + { + "changes": [ + { + "after": " if prod(map(len, options)) >= 4096:\n _refuse(\n InsuredUnsupportedReason.UNKNOWN_EARNINGS,\n", + "before": " if prod(map(len, options)) > 4096:\n _refuse(\n InsuredUnsupportedReason.UNKNOWN_EARNINGS,\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-completions_cap_inclusive.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/completions_cap_inclusive /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_completions_refuse_past_4096[1960-3-False]" + ], + "log": "scratch/review/round24-mutation-completions_cap_inclusive.log", + "name": "completions_cap_inclusive", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-completions_cap_inclusive.json" + }, + { + "changes": [ + { + "after": " (tuple(sorted(chosen)), 0)\n", + "before": " (tuple(sorted((*fixed, *chosen))), 0)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-completions_drop_fixed.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/completions_drop_fixed /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_completions_keep_a_deferred_year_s_fixed_quarters" + ], + "log": "scratch/review/round24-mutation-completions_drop_fixed.log", + "name": "completions_drop_fixed", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-completions_drop_fixed.json" + }, + { + "changes": [ + { + "after": " yield {**lower, **dict(zip(years, chosen, strict=True))}\n", + "before": " yield {**upper, **dict(zip(years, chosen, strict=True))}\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-completions_rest_at_lower.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/completions_rest_at_lower /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_completions_list_quarter_sets_before_1978_and_counts_after" + ], + "log": "scratch/review/round24-mutation-completions_rest_at_lower.log", + "name": "completions_rest_at_lower", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-completions_rest_at_lower.json" + }, + { + "changes": [ + { + "after": " return\n periods = tuple(\n (_qid(p.start), _qid(p.end)) for p in person.prior_disability_periods\n )\n years = {q // 4 for pair in periods for q in pair} & upper.keys()\n", + "before": " periods = tuple(\n (_qid(p.start), _qid(p.end)) for p in person.prior_disability_periods\n )\n years = {q // 4 for pair in periods for q in pair} & upper.keys()\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-guard_off.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/guard_off /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_a_middle_completion_past_the_boundary_cap_refuses" + ], + "log": "scratch/review/round24-mutation-guard_off.log", + "name": "guard_off", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-guard_off.json" + }, + { + "changes": [ + { + "after": "", + "before": " _refuse_boundary_completions(person, lower, upper)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-guard_call_dropped.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/guard_call_dropped /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_a_middle_completion_past_the_boundary_cap_refuses" + ], + "log": "scratch/review/round24-mutation-guard_call_dropped.log", + "name": "guard_call_dropped", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-guard_call_dropped.json" + }, + { + "changes": [ + { + "after": "", + "before": " if all(lower[year] == upper[year] for year in years):\n return\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-guard_no_skip.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/guard_no_skip /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_known_endpoint_years_leave_the_cap_to_the_record" + ], + "log": "scratch/review/round24-mutation-guard_no_skip.log", + "name": "guard_no_skip", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-guard_no_skip.json" + }, + { + "changes": [ + { + "after": " if assignments >= 4096:\n", + "before": " if assignments > 4096:\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-guard_inclusive.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/guard_inclusive /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_the_boundary_guard_refuses_only_past_4096" + ], + "log": "scratch/review/round24-mutation-guard_inclusive.log", + "name": "guard_inclusive", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-guard_inclusive.json" + }, + { + "changes": [ + { + "after": " year, through_quarter=year * 4 + 3, death_quarter=None\n", + "before": " year, through_quarter=year * 4 + 3, death_quarter=death\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-guard_ignores_death.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/guard_ignores_death /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_the_boundary_guard_counts_no_quarter_after_death" + ], + "log": "scratch/review/round24-mutation-guard_ignores_death.log", + "name": "guard_ignores_death", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-guard_ignores_death.json" + }, + { + "changes": [ + { + "after": " for flexible in (upper[year][1],)\n", + "before": " for flexible in range(low, upper[year][1] + 1)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-guard_upper_count_only.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/guard_upper_count_only /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_a_middle_completion_past_the_boundary_cap_refuses" + ], + "log": "scratch/review/round24-mutation-guard_upper_count_only.log", + "name": "guard_upper_count_only", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-guard_upper_count_only.json" + }, + { + "changes": [ + { + "after": " for flexible in (low,)\n", + "before": " for flexible in range(low, upper[year][1] + 1)\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-guard_lower_count_only.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/guard_lower_count_only /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_a_middle_completion_past_the_boundary_cap_refuses" + ], + "log": "scratch/review/round24-mutation-guard_lower_count_only.log", + "name": "guard_lower_count_only", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-guard_lower_count_only.json" + }, + { + "changes": [ + { + "after": " vacant = len(allowed)\n", + "before": " vacant = len(set(allowed) - set(fixed))\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-guard_counts_fixed_quarters.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/guard_counts_fixed_quarters /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_the_boundary_guard_leaves_fixed_quarters_out" + ], + "log": "scratch/review/round24-mutation-guard_counts_fixed_quarters.log", + "name": "guard_counts_fixed_quarters", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-guard_counts_fixed_quarters.json" + }, + { + "changes": [ + { + "after": " if not _prior_passes(\n person, upper, index, exit_month, blind=blind, **options\n ):\n return blind\n", + "before": " if _prior_passes(\n person, upper, index, exit_month, blind=blind, **options\n ):\n return blind\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-prior_basis_inverted.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/prior_basis_inverted /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_a_year_that_can_leave_an_unflagged_prior_unsupported_refuses[None-outcome0]" + ], + "log": "scratch/review/round24-mutation-prior_basis_inverted.log", + "name": "prior_basis_inverted", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-prior_basis_inverted.json" + }, + { + "changes": [ + { + "after": " year for year in upper if year < start and lower[year] != upper[year]\n", + "before": " year for year in upper if year <= start and lower[year] != upper[year]\n" + } + ], + "command": "env POPULACE_DYNAMICS_PSID_DIR=/nonexistent/trackb-round24 POPULACE_DYNAMICS_EPUF_DIR=/nonexistent/trackb-round24 OMP_NUM_THREADS=1 OMP_WAIT_POLICY=PASSIVE POLARS_MAX_THREADS=1 PYTHONPATH=/home/user/w562/src:/home/user/w562 PYTHONDONTWRITEBYTECODE=1 TRACKB_ROUND24_MUTATION=scratch/review/round24-mutation-flag_fits_before_start.json HYPOTHESIS_STORAGE_DIRECTORY=scratch/review/hyp24/flag_fits_before_start /tmp/tbvenv/bin/python scratch/review/run_round24_named.py -p no:xdist -p no:cacheprovider -q -x --tb=line -rf tests/test_track_b_insured_status_fix_round_24.py tests/test_track_b_insured_status_fix_round_23.py tests/test_track_b_insured_status_fix_round_22.py tests/test_track_b_insured_status_fix_round_21.py tests/test_track_b_insured_status_fix_round_20.py tests/test_track_b_insured_status_fix_round_19.py tests/test_track_b_insured_status_status_stress.py tests/test_track_b_insured_status_fix_round_18.py tests/test_track_b_insured_status_fix_round_17.py tests/test_track_b_insured_status_classification_oracle.py tests/test_track_b_insured_status_fix_round_16.py tests/test_track_b_insured_status_status_oracle.py tests/test_track_b_insured_status.py tests/test_track_b_insured_status_contract.py tests/test_track_b_insured_status_fix_round_10.py tests/test_track_b_insured_status_fix_round_10_proof.py tests/test_track_b_insured_status_fix_round_11.py tests/test_track_b_insured_status_fix_round_12.py tests/test_track_b_insured_status_fix_round_13.py tests/test_track_b_insured_status_fix_round_14.py tests/test_track_b_insured_status_fix_round_15.py tests/test_track_b_insured_status_fix_round_2.py tests/test_track_b_insured_status_fix_round_3_coverage.py tests/test_track_b_insured_status_fix_round_3_periods.py tests/test_track_b_insured_status_fix_round_3_validation.py tests/test_track_b_insured_status_fix_round_4_docs.py tests/test_track_b_insured_status_fix_round_4_endings.py tests/test_track_b_insured_status_fix_round_4_routes.py tests/test_track_b_insured_status_fix_round_5_continuity.py tests/test_track_b_insured_status_fix_round_5_possibility.py tests/test_track_b_insured_status_fix_round_5_sspa.py tests/test_track_b_insured_status_fix_round_6_ordering.py tests/test_track_b_insured_status_fix_round_6_routes.py tests/test_track_b_insured_status_fix_round_7.py tests/test_track_b_insured_status_fix_round_8.py tests/test_track_b_insured_status_fix_round_9.py tests/test_track_b_insured_status_mutations.py tests/test_track_b_insured_status_period_declarations.py tests/test_track_b_insured_status_qc.py tests/test_track_b_insured_status_readings.py tests/test_track_b_insured_status_sources.py", + "exit_code": 1, + "failing_test_nodes": [ + "tests/test_track_b_insured_status_fix_round_24.py::test_either_bound_of_a_start_year_can_unseat_a_flagged_prior[counts0-None-outcome0]" + ], + "log": "scratch/review/round24-mutation-flag_fits_before_start.log", + "name": "flag_fits_before_start", + "open_audit": { + "os.system": 0, + "restricted_opens": 0, + "subprocess.Popen": 0 + }, + "source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89", + "spec_path": "scratch/review/round24-mutation-flag_fits_before_start.json" + } + ], + "round_24_runner_source": "\"\"\"Run named invented-data conformance tests with open-event auditing.\"\"\"\n\nimport hashlib\nimport json\nimport os\nfrom pathlib import Path\nimport sys\n\nCOUNTS = {\"restricted_opens\": 0, \"subprocess.Popen\": 0, \"os.system\": 0}\nBARRED = {\n \"gates.yaml\", \"adjusted_poverty.py\", \"rows.py\",\n \"ssa_trust_fund_interest_rates_2026.json\",\n \"urban2010_cola_comparison.md\", \"urban2010_fra68_comparison.md\",\n \"boomers2004_uniform_cut_comparison.md\", \"minimum_benefits_comparison.md\",\n \"m6_projection_engine.md\", \"mint8_table_user_guide.source.html\",\n \"test_anchor_provenance_erratum.py\",\n \"s0_1_power_results.json\", \"s0_1_source_audit.md\", \"s0_1_power.py\",\n \"test_s0_1_invariants.py\", \"test_s0_1_power.py\",\n \"test_s0_1_thresholds.py\",\n}\n\n\ndef audit(event, arguments):\n if event == \"open\" and isinstance(arguments[0], (str, bytes)):\n path = os.fsdecode(arguments[0])\n name = Path(path).name\n if (\n name in BARRED\n or name.startswith((\"adjusted_poverty.\", \"rows.\"))\n or \"/PolicyEngine/psid-data/\" in path\n or \"/microcosm-launch-evidence/\" in path\n or \"/dynasim-refs/\" in path\n or \"/claude-501/\" in path\n or \"/tests/s0_1/\" in path\n or \"/tests/acola_track/\" in path\n or \"/tests/cola_track_a/\" in path\n or \"/tests/fra68_track/\" in path\n ):\n COUNTS[\"restricted_opens\"] += 1\n raise RuntimeError(path)\n elif event in (\"subprocess.Popen\", \"os.system\"):\n COUNTS[event] += 1\n\n\ndef main():\n for name in (\"POPULACE_DYNAMICS_PSID_DIR\", \"POPULACE_DYNAMICS_EPUF_DIR\"):\n assert os.environ[name] == \"/nonexistent/trackb-round24\"\n assert sys.argv[1:]\n assert all(\n not argument.startswith(\"tests/\") or \".py\" in argument\n for argument in sys.argv[1:]\n )\n sys.addaudithook(audit)\n from populace_dynamics.track_b import insured_status as insured\n\n source_path = Path(insured.__file__)\n original = source_path.read_bytes()\n baseline_path = os.environ.get(\"TRACKB_ROUND16_SOURCE\")\n if baseline_path:\n baseline = Path(baseline_path).read_bytes()\n exec(compile(baseline, str(source_path), \"exec\"), insured.__dict__)\n print(\"BASELINE\", hashlib.sha256(baseline).hexdigest(), flush=True)\n spec_path = os.environ.get(\"TRACKB_ROUND24_MUTATION\")\n if spec_path:\n spec = json.loads(Path(spec_path).read_text())\n assert hashlib.sha256(original).hexdigest() == spec[\"source_sha256\"]\n source = original.decode()\n for change in spec[\"changes\"]:\n assert source.count(change[\"before\"]) == 1, change[\"before\"]\n source = source.replace(change[\"before\"], change[\"after\"], 1)\n exec(compile(source, str(source_path), \"exec\"), insured.__dict__)\n print(\"MUTATION\", spec[\"name\"], flush=True)\n import pytest\n\n try:\n return pytest.main(sys.argv[1:])\n finally:\n assert source_path.read_bytes() == original\n print(\"OPEN_AUDIT\", json.dumps(COUNTS, sort_keys=True), flush=True)\n\n\nif __name__ == \"__main__\":\n raise SystemExit(main())\n", + "round_24_note": "A cloud session ran round 24's 135 mutations at d30e4426 against every insured status module, with no restricted open (PR #562 comment 6620539979). The run takes round 23's 107, with precedence_possible re-anchored to drop only the _refuse_unsupported_priors call, and adds 28 of round 24's own. All 135 failed a named test. The comment's base64 block miscopies one character, at offset 5037 (B for F). With F restored, the block passes gzip's CRC check and matches the SHA-256 the comment gives for the file, fa546be3a8772982165a9bc40a0f212179735a27b10792c1cb02ce052e83fcae, and these records come from that file.", + "round_24_test_sha256": { + "tests/test_track_b_insured_status_fix_round_24.py": "0f9f213f9e6b08d834360ee3f16afba1d8f3e371c574895340ddb5abbe364613", + "tests/test_track_b_insured_status_fix_round_23.py": "c62b0088c4c904e8847325189f7a7b693d9b3a9df182973ea9a875edbf382917", + "tests/test_track_b_insured_status_fix_round_19.py": "735433c50e252f3bfcdc4c11019c52d750ddfe97dbb3195d3e51bff511175b59", + "tests/test_track_b_insured_status_fix_round_2.py": "c1d00971949eb7d1f9ac458dfea1b5e47922fb3d0047a50a764e7400f9321835", + "tests/test_track_b_insured_status_fix_round_20.py": "f15ef8610de8fb6138f485588ff188c6748e34ebd5cb51ee2f55735d2fa9c4cd", + "tests/test_track_b_insured_status_fix_round_22.py": "4501efa1c9864ddd802c9be8836d7f3ff8dade677a890da596d7a8fb68977ef9", + "tests/test_track_b_insured_status_fix_round_21.py": "dd858c630cbd0473745568cdcf92ac28b350bd4efe06e35f5be1f4c264b3aa04", + "tests/test_track_b_insured_status_status_stress.py": "882e3b1f0a1c91fd126d8ba85da50fd7672b475b13b81eb48e132d470cd27bed" + }, + "round_24_replay": "Write round_24_runner_source to scratch/review/run_round24_named.py. For each round_24_mutations record, write name/source_sha256/changes to its spec_path, then execute its exact command at d30e4426. Mutations apply only in memory.", + "round_24_final_source_sha256": "7d2d202b02bfcc14ee4d988cb35bef8706bf28de7af494fd6bad2f674ca80c89" }