Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,16 @@ if git diff --cached --name-only | grep -qE '^(test/.*\.py|skills/trz-expert/scr
fi
rm -f /tmp/trz-kchecker.$$
echo "pre-commit: K5/K6 checker matches the manifest"

echo "pre-commit: B/F/I checker against generate_wide.py's manifest, 25 seeds"
if ! "$PY" test/audit_test.py --seeds 25 > /tmp/trz-audit.$$ 2>&1; then
cat /tmp/trz-audit.$$
rm -f /tmp/trz-audit.$$
echo
echo "Commit stopped: audit.py disagrees with generate_wide.py's manifest "
echo "or expected_findings.md. To skip: git commit --no-verify"
exit 1
fi
rm -f /tmp/trz-audit.$$
echo "pre-commit: B/F/I checker matches the manifest"
fi
9 changes: 9 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,13 @@ jobs:
# what would have caught it.
run: python test/k_checker_test.py --seeds 300

- name: B/F/I computed from a workbook, against generate_wide.py's manifest
# scripts/audit.py's own hand-built fixtures for I5/B5, the suite-1 static
# fixture checked against expected_findings.md (including the part-time row
# that must stay silent - the exact row that caught a false positive in this
# script before anyone else did), plus 300 seeds for I1/B4/F5.
run: python test/audit_test.py --seeds 300

- name: Suite 5 - the chain below the payroll
# ведомост -> обр. 1 -> обр. 6 -> внесено, one link broken at a time. The
# checks that reconcile the payroll against the documents downstream of it had
Expand Down Expand Up @@ -315,3 +322,5 @@ jobs:
run: python test/run_tests.py --seeds 3000
- name: K5/K6 checker at the same depth
run: python test/k_checker_test.py --seeds 3000
- name: B/F/I checker at the same depth
run: python test/audit_test.py --seeds 3000
19 changes: 19 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ python test/checks_test.py # suite 1: static payroll against the key in expec
python test/eval_skill.py --selftest # free: checks the refusal grading itself
python test/preflight_test.py # scripts/preflight.py: clean is silent, each shape defect found once
python test/k_checker_test.py # scripts/k_checker.py: K5/K6 vs. generate_wide.py's manifest, 60 seeds by default
python test/audit_test.py # scripts/audit.py: I1/B4/F5 vs. the manifest, B1/I5/B5 vs. hand-built and suite-1 fixtures
python test/komplekt_test.py # suite 5: ведомост -> обр. 1 -> обр. 6 -> внесено -> счетоводство, one link at a time
python test/lifecycle_test.py # suite 6: five months of the same people, one timeline break at a time
python test/run_tests.py # all five, 50 seeds
Expand Down Expand Up @@ -128,6 +129,24 @@ A false positive fails exactly like a miss.
`preflight.py`'s own `SKILL_DIR`-relative path to `stavki.md`, and the pre-commit
hook's trigger regex - a change under `scripts/` that stops matching that regex would
go untested locally again, the exact failure mode the move was meant to close.
- **`scripts/audit.py` (2.18.0) covers I1, I5 (narrow), B1, B4, B5 and F5 - not the
rest of B/F/I/K.** Each is mechanical (a row's own numbers, or a rate read fresh
from `references/stavki/` via `scripts/rates.py`, never typed into either file) and
safe for a generic tool - B2/B3/B6 need a company-specific number `mapping.yaml`
doesn't carry, F1/F2/F3/F4/F6/F7/F9's composition method needs a judgment call this
script isn't positioned to make safely yet, F8/F10 need information one workbook
doesn't hold, and K1/K3/K4/K7/K8 are `k_checker.py`'s same closed-vocabulary risk.
Building it against `generate_wide.py` at scale (not just a hand-built fixture)
found a real, pre-existing `preflight.py` vocabulary bug before it ever shipped:
"НЕТО преди удръжки"/"НЕТО за изплащане" and "Вноски работодател ДОО+ТЗПБ"/"Вноски
работодател общо" both collapsed into one concept each, raising the blocking
`DUPLICATE_CONCEPT` signal on every realistic fixture and stopping every check cold -
split now, the same way "Клас %"/"Клас сума" already were. B1/B5 also went through
two rounds of false positives from partial attendance (part-time hours, then a
partial month from leave/sick days) before landing on "the highest count declared
on the sheet" as the least-wrong stand-in for the full-time/full-month norm this
script has no public-holiday calendar to compute directly - the suite-1 fixture's
own part-time row (Стефка Ангелова) caught the first one.
- **Suite 6 may only compare a month with another month.** Every sheet in
`test/generate_lifecycle.py` is internally correct on purpose — the arithmetic
reconciles, the bases are right, each month would pass suites 1–4 alone. The only thing
Expand Down
6 changes: 6 additions & 0 deletions skills/trz-expert/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,12 @@ fs = openpyxl.load_workbook(path, data_only=False) # формулите
(`references/proverki/k.md`) носи и „Как се чете електронна таблица“ пред своите
проверки, и „Формули“ след тях.

За I1, I5 (само липсващи дни болничен при начислена сума), B1, B4, B5 и F5 скилът носи
`scripts/audit.py` — смята ги директно от файла, вместо да ги пресмяташ наум; ставките
идват свежи от `references/stavki/` при всяко изпълнение, не са вградени в скрипта.
Пусни го и вземи находките му за тези шест, преди да преминеш ръчно през тях; другите
проверки на B, F и I остават на анализа тук.

Изпълни проверките от всяка отворена група ред по ред. Всяка има изричен резултат — един от
пет: преминава, не преминава, **недостатъчни данни** (проверката се дължи, но нещо липсва —
назови точно какво), **непроверимо** (документът е подаден, но не става за проверка —
Expand Down
Loading