Skip to content

Add academic_year period type to the source-package contract - #136

Open
juaristi22 wants to merge 1 commit into
PolicyEngine:mainfrom
juaristi22:add-academic-year-period-type
Open

Add academic_year period type to the source-package contract#136
juaristi22 wants to merge 1 commit into
PolicyEngine:mainfrom
juaristi22:add-academic-year-period-type

Conversation

@juaristi22

Copy link
Copy Markdown
Collaborator

Closes #131.

Lane: ledger-contract-maintainer (.github/ledger-agents.yml) — judges ledger-contract + ledger-boundary. This is the one contract change the UK target migration needs, isolated per #131 so no data wave drags through contract review. Unblocks the SLC packages in #132 (wave 1) and #133 (slc_repayments).

What changed

  • ledger/core.pyacademic_year joins ALLOWED_PERIOD_TYPES, with a comment documenting the period-integer convention for split-label years: the stored integer is the opening year of the publisher's label — UK FY2024-25 → fiscal_year 2024 (the existing packages/hmrc/vat_firm_targets_2024_25 precedent), AY 2024/25 → academic_year 2024. Publishers that label a fiscal year with a single year keep that label year (US federal FY2025 → 2025).
  • docs/schemas/consumer_fact.v1.schema.json + policyengine_ledger/schemas/consumer_fact.v1.schema.json — byte-identical description added to period.type documenting the vocabulary and the opening-year convention. Deliberately a description, not an enum: the single enforcement point for the vocabulary stays validate_fact; the schema documents, it does not duplicate the gate.
  • Teststest_ledger_core.py: academic_year facts validate; unknown period types still fail with malformed_period. test_ledger_consumer_contract.py: full round trip — two academic_year facts → write_consumer_facts_jsonlbuild_consumer_artifact (profile shipped through the artifact) → load_consumer_artifact (schema-validates every row) → resolve_profile_targets at {type: academic_year, value: 2024} resolves the exact fact on fact basis.

Behavior notes

  • CONSUMER_FACT_SCHEMA_SHA256 derives from the packaged schema bytes, so it moves with this change. Newly built artifacts carry the new sha; load_consumer_artifact will reject artifacts whose manifests pin the old sha — the designed exact-contract behavior. Existing consumer artifacts need a rebuild with the matching wheel.
  • Period-integer alignment downstream (e.g. policyengine-uk-data's AY 2024/25 → calendar 2025 mapping) is a consumer concern; facts store what the publisher asserted.
  • No existing package or fact changes behavior: the vocabulary only widens, and the schema edit is documentation-only for row validation.

Checks

  • uv run ruff check ledger policyengine_ledger db scripts tests (repo-pinned, CI scope) — clean.
  • Full uv run pytest -q — green on this branch (614 passed, 1 skipped).
  • Deterministic checks per the lane: schema validation, consumer-contract validation, package import compatibility, raw-facts boundary validation — all exercised by the suite above.

🤖 Generated with Claude Code

UK student-finance publications (SLC/DfE EES) assert academic-year
periods; the vocabulary had no way to state that without re-labelling
AY 2024/25 as a calendar or fiscal year. Adds academic_year to
ledger.core.ALLOWED_PERIOD_TYPES, documents the opening-year integer
convention (FY2024-25 -> 2024, AY 2024/25 -> 2024) beside the
vocabulary and in the consumer schema's period.type description (both
byte-identical schema copies), and proves the contract end to end:
validate_fact accepts academic_year and rejects unknown types, and an
academic_year fact set builds into a consumer artifact, loads, and
resolves at {type: academic_year, value: 2024}.

The JSON schema deliberately gains a description, not an enum: the
single enforcement point for the vocabulary stays validate_fact.

Closes PolicyEngine#131.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

Add academic_year period type to the source-package contract

1 participant