feat: audit.py computes F1/F9/F10's insurable-income-side composition - #115
Merged
Conversation
Continuing point 1 of the trz-expert evaluation, one deliberately-bounded step further than 2.18.0: the "solve the composition" method proverki.md describes for F1/F6/F10, ported faithfully from test/structural_test.py rather than reimplemented from the prose description, because that exact code needed several seed-specific bug fixes to get right even against the synthetic model with fixed column names (the file's own comments name two of them). What it does: enumerates subsets of the contested elements (доход в натура, excess over the social-expense threshold) to find which one, together with the two statute-settled placements (болнични always inside - чл. 3, ал. 1 НЕВДПОВ; чл. 224 always outside - чл. 1, ал. 8, т. 7 НЕВДПОВ), explains the declared insurable income. Never settles which contested reading is correct: the file's own practice is inferred from at least three usable rows with a clear 2/3 majority, and only rows disagreeing with THAT practice are findings (F10_in_kind_asymmetry, F10_excess_asymmetry). Where practice can't be established, only the two statutory placements are still checked (F1_compensation_in_insurable, F9_sick_pay_out_of_insurable) by enumerating every placement of the contested elements instead of assuming one. Deliberately scoped to the INSURABLE-income side only. F10_in_kind_asymmetry and F10_excess_asymmetry can also arise from the taxable-base side, which needs the same composition method plus every placement of the чл. 19, ал. 2 relief enumerated against it (F6/F7/F9's remaining piece) - left to the model as an explicitly separate future increment, not attempted here. Gated on the sheet having zero unrecognised columns at all: an unrecognised accrual/benefit column would make a real composition silently unreachable, the same false-positive risk that already limited K1/K3/K4/K7 in k_checker.py. In practice this means a mapping.yaml that declares every administrative/breakdown column as `ignore` - both SKILL.md and this file's own docstring say so. Verification method: comparing against test/generate_wide.py's manifest alone would have been misleading, because F10_in_kind_asymmetry/excess_asymmetry can legitimately arise from either side of the composition and the manifest does not say which. So the three ids that are UNIQUELY insurable-side (F1_insurable_unexplained, F1_compensation_in_insurable, F9_sick_pay_out_of_insurable) are compared against the manifest exactly - 92, 26 and 53 out of 300 seeds, zero misses, zero false positives - while the two shared ids are checked only for false positives against the manifest, and separately cross-validated directly against test/structural_test.py's own reference implementation (not just its pass/fail summary) across 300 seeds: zero mismatches once its taxable-side occurrences were excluded, confirming every one of this script's misses is the deferred taxable-side piece, none of them an insurable-side bug. Confirmed the test has teeth: broke the practice-majority threshold from 2/3 to effectively-unanimous and watched six seeds fail before restoring it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XvbzEbQwxwxxHAtXfPMrno
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Continuing point 1 of the trz-expert evaluation, one deliberately-bounded step past 2.18.0: the "solve the composition" method
proverki.mddescribes for F1/F6/F10, ported faithfully fromtest/structural_test.pyrather than reimplemented from the prose — that exact code needed several seed-specific bug fixes to get right even against the synthetic model with fixed column names.Enumerates subsets of the contested elements (in-kind benefits, excess over the social-expense threshold) to find which one, plus the two statute-settled placements (sick pay always in, чл. 224 always out), explains the declared insurable income. Never settles which contested reading is correct — the file's own practice is inferred from ≥3 usable rows with a clear 2/3 majority; only rows disagreeing with that are findings.
Deliberately scoped to the insurable-income side only.
F10_in_kind_asymmetry/F10_excess_asymmetrycan also arise from the taxable-base side (needs the composition method plus every placement of the чл. 19 relief enumerated against it) — left as an explicit future increment, not attempted here given how bug-prone that exact combination was for the original authors.Gated on zero unrecognised columns on the sheet (same false-positive risk that already limited K1/K3/K4/K7 in
k_checker.py) — in practice requires amapping.yamldeclaring every administrative/breakdown column asignore.Verification
Comparing against
generate_wide.py's manifest alone would have been misleading, since two of the five ids can legitimately arise from either side of the composition. So:F1_insurable_unexplained,F1_compensation_in_insurable,F9_sick_pay_out_of_insurable) compared exactly against the manifest — 92/26/53 across 300 seeds, zero misses, zero false positives.test/structural_test.py's own reference implementation (not just its pass/fail summary) across 300 seeds — zero mismatches once taxable-side occurrences were excluded, confirming every miss is the deferred piece, none an insurable-side bug.🤖 Generated with Claude Code
https://claude.ai/code/session_01XvbzEbQwxwxxHAtXfPMrno