Skip to content

Official-calculator oracles (mode 3): closed-set extension, dated-reading provenance, calculator work list - #64

Open
vahid-ahmadi wants to merge 2 commits into
uk/ukmod-cases-schemafrom
uk/calculator-oracles
Open

Official-calculator oracles (mode 3): closed-set extension, dated-reading provenance, calculator work list#64
vahid-ahmadi wants to merge 2 commits into
uk/ukmod-cases-schemafrom
uk/calculator-oracles

Conversation

@vahid-ahmadi

Copy link
Copy Markdown
Contributor

Stacked on #49 (uk/ukmod-cases-schema) — retarget to main when #49 merges; the diff shown here is this lane's own work only.

What's here

  • Oracle vocabulary: five calculator oracle ids join the closed set (govuk_income_tax_estimator, govuk_hicbc_calculator, policy_in_practice_boc, entitledto, turn2us). CALCULATOR_ORACLES marks them as live services: their CaseResult.oracle_version must carry the reading date (YYYY-MM-DD) — enforced at validation — and SCHEMA.md documents the provenance rule (archive every reading; manual or terms-compliant access, one case at a time, never a scrape). oracle_version is now required non-empty for model oracles too.
  • Three new boundary cases (inputs + rationale only, per the battery doctrine): HICBC full clawback at exactly £80,000; the £125,140 double boundary (personal allowance exactly zero, additional rate begins); PSA ordering on £1,500 savings interest (expected extra liability exactly £100). Statutory 2025-26 values verified against gov.uk/LITRG; cases pinned to policy year 2025 accordingly.
  • battery/calculator_set.json + load_calculator_set(): the 10-case starter work list from Official-calculator oracles (mode 3): gov.uk and benefits-calculator household cases as a second UK oracle family #63 — each case assigned to ≥ 2 calculators so a PE-vs-UKMOD disagreement always has an adjudicating third reading; the two-child abolition pair gets three production-calculator readings each. Fail-loud validation: unknown case id, fewer than two oracles, a model oracle in the set, duplicates, and empty notes all raise.

No CaseResult rows and no expected values are committed — readings come from the real calculators later, dated and archived.

Suite: 174 passed / 4 skipped (was 164); ruff format --check clean.

Builds #63.

🤖 Generated with Claude Code

@DTrim99

DTrim99 commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

Review — Official-calculator oracles (mode 3)

Enforcement is real code, not just SCHEMA.md prose: CaseResult.__post_init__ (case_diffs.py:283-294) raises when oracle_version is blank and when a CALCULATOR_ORACLES row lacks an ISO date; the closed set is enforced via Oracle(o) / CALCULATOR_ORACLES membership in load_calculator_set. Both paths are tested (test_case_schema.py:393-399, 464-480), and there are no id collisions across the 5 new oracle ids. I verified the three boundary cases against 2025/26 UK rules and they're exact:

  • HICBC £80,000 — 1%/£200 over £60k → 100% clawback at £80k ✓
  • £125,140 — £100k + 2×£12,570 = PA nil = additional-rate threshold ✓
  • PSA — £30k earnings stays basic-rate → £1,000@0% + £500@20% = £100 extra ✓

Should address

Suggestion

  • The provenance rule (SCHEMA.md:190-208, "archive every reading / never scrape / one case at a time") is documentation only — nothing asserts an archive citation exists on the eventual result row. Consider requiring an archive token in annotations for CALCULATOR_ORACLES rows at validation, or the rule stays unenforced.

Reviewed with Claude Code assistance.

r and others added 2 commits August 19, 2026 14:07
…d-reading provenance, 10-case calculator work list

- Oracle enum grows five calculator ids (govuk_income_tax_estimator,
  govuk_hicbc_calculator, policy_in_practice_boc, entitledto, turn2us);
  CALCULATOR_ORACLES marks them as live services whose result rows must
  carry the reading date (YYYY-MM-DD) in oracle_version, enforced at
  validation, with the archive-the-reading rule documented in SCHEMA.md.
  oracle_version is now required non-empty for every oracle.
- Three new boundary cases (2025-26 statutory values, verified against
  gov.uk/LITRG): HICBC full clawback at exactly GBP 80,000, the
  zero-allowance/additional-rate double boundary at GBP 125,140, and PSA
  ordering with GBP 1,500 savings interest (expected extra liability
  exactly GBP 100). Inputs + rationale only, per the battery doctrine.
- battery/calculator_set.json + load_calculator_set(): the 10-case
  starter work list, each case into >= 2 calculators so PE-vs-UKMOD
  splits always have an adjudicating third reading; entries validate
  against the battery (unknown case, single oracle, model oracle in the
  set, duplicate, empty notes all raise).

Suite: 174 passed / 4 skipped (was 164); ruff format clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…r rows

Review items from the 2026-08-18 pass:
- _contains_iso_date now parses every shape-matching chunk with
  date.fromisoformat, so "2026-13-45" / "0000-00-00" / "2025-02-30"
  fail; "2024-02-29" passes.
- The SCHEMA.md archive rule is validation, not prose: a
  calculator-oracle row must carry an "archive: <path-or-url>"
  annotation citing the archived reading, or it raises. Model oracles
  (UKMOD/TAXSIM) are unaffected.

Also rebased onto uk/ukmod-cases-schema @ a1d57d7 (schema_version,
variable_class, classify->CaseResult seam), resolving the test-file
overlap additively.

Suite: 190 passed, 4 skipped.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vahid-ahmadi
vahid-ahmadi force-pushed the uk/calculator-oracles branch from ec749c8 to f3e9bb8 Compare August 19, 2026 13:09
@vahid-ahmadi

Copy link
Copy Markdown
Contributor Author

Both should-address items plus the suggestion addressed in f3e9bb8 (rebased onto the updated #49 branch, a1d57d7):

Item Fix
_contains_iso_date shape-only Every shape-matching chunk is now parsed with date.fromisoformat2026-13-45, 0000-00-00, and 2025-02-30 all fail validation; 2024-02-29 passes. Tests pin all four.
Merge ordering Acknowledged — this stays stacked behind #49 (now also carrying its own review fixes: schema_version, variable_class, the classify→CaseResult seam), and the test-file overlap was resolved additively in the rebase.
Archive rule unenforced (suggestion) Taken: a calculator-oracle row now requires an archive: <path-or-url> annotation citing the archived reading or it raises; model oracles (UKMOD/TAXSIM) are unaffected. SCHEMA.md updated to say the rule is validation, not prose.

Suite: 190 passed / 4 skipped; ruff clean. Force-pushed with lease for the rebase.

@DTrim99

DTrim99 commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

Re-review — addressed ✅

  • _contains_iso_date now parses each candidate with date.fromisoformat in try/except (I confirmed 2026-13-45 / 0000-00-00 / 2025-02-30 reject and the leap day accepts), with test_impossible_reading_dates_rejected / test_real_reading_date_accepted.
  • Provenance rule is now enforced, not just documented: ARCHIVE_PREFIX + __post_init__ rejects any CALCULATOR_ORACLES row without an archive: annotation, with tests.
  • Boundary cases (HICBC £80k, £125,140, PSA) unchanged and still correct.

Only open item is the merge ordertest_loads_against_battery and the 7 referenced case_ids depend on #49, so this needs to land after #49 (expected for the stack, not a code fix).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants