Add HMRC CGT Table 4 BADR and Investors’ Relief facts - #288
Conversation
CI fixes
Verification
|
vahid-ahmadi
left a comment
There was a problem hiding this comment.
Review at d505ccd9 (worktree; two commits on 5324aa27; merge-tree clean). Local: test_chronicle_source_package.py + test_chronicle_governance.py 126 passed; ruff check/format (locked 0.14.10) clean; git diff --check clean; the full suite was still running with no failures when I posted, and CI is in progress.
Fidelity, judged. The vendored workbook is 6,559 bytes at sha256 7bd0098…442d5ca, matching the manifest and the media URL on the gov.uk collection page ("last updated 27 August 2026", Table 4 to 2024-25). Reading the ODS directly gives 32 / 32 / 31 / 31 numeric cells across the four sheets, 126 in all, and mapping every emitted fact back to its (sheet, column, row) gives a bijection: 0 mismatches, 0 unused numeric cells. Eight values spot-checked cell against fact, including 2024-25 individuals 61k / £18,443m / £1,821m, the all-taxpayer £18,475m gains, the trusts £3m tax, one band row and two earlier years; units (thousands → count, £m → gbp) and tax-year periods (6 Apr–5 Apr, same convention as the carried-interest and country-region packages) are right. The six suppressed cells ([Fewer than 1] ×4 trust counts, [Less than 1] ×2 £0-band tax) are retained as text cells, declared as guard cells with expected values, and referenced by no fact; the complementary record sets exclude exactly those six.
Boundary, judged. 14 record sets over the three published columns only; scale and period metadata; no shares, rates or derived values. Concepts hmrc.cgt_badr_ir_{taxpayers,qualifying_gains,tax} collide with nothing under hmrc.cgt_*, and the notes say these are relief-qualifying gains before losses and the exempt amount, not all-CGT gains.
Core code. Two one-line registrations (source_package.py:104, bundle.py:109); the bundle test's expected counts move by exactly +126 everywhere and reconcile.
Two notes for downstream, not for this PR: individuals / trusts / all are a taxpayer_type dimension here (as in Table 8b) rather than concept suffixes (as in Tables 1/2), so a microcosm selection on concept alone would mix them; and the record sets are carved around the suppressed cells, so select by taxpayer_type and the gain band, never by record-set id. Body says "as of 24 September"; cosmetic.
Both pending specialist checks pass on my reading. Approving; fine to take out of draft once CI is green.
Summary
Add HMRC's 2026 Capital Gains Tax Table 4 as a pinned Chronicle source package. The package emits 126 source-backed facts for Business Asset Disposal Relief and Investors' Relief taxpayer counts, qualifying gains, and tax charged across tax years 2021–22 to 2024–25.
The workbook contains four suppressed trust-count cells and two suppressed tax cells. Chronicle preserves their source text and emits no numeric facts for them. Complementary record-set regions on each sheet exclude only those six cells. The package uses concepts distinct from the all-CGT measures in Tables 1 and 2.
HMRC's collection page lists the 2026 annual release as the latest, updated 27 August 2026. Its Table 4 workbook ends at 2024–25; there is no later vintage to add as of 24 September 2026.
Fixes #287.
Chronicle governance
ledger-source-ingestor.7bd0098913e44e3c79a533690cd25ee08f627cd72935c46a874a7eab5442d5ca; package, source-cell, fact, and consumer-contract validation pass. The full source-suite build reports 126 facts, 126 lineaged source records, and zero agent-acceptance errors.ledger-source-fidelity: pending specialist review. The 126 numeric cells correspond to the 126 emitted facts; tests check every 2024–25 band, all four individual totals, and all six suppressed source cells.ledger-contract: no schema or consumer-contract change.ledger-boundary: pending specialist review. The package emits HMRC's published levels with unit scaling and period metadata. It contains no imputation, aging, reconciliation, or calibration binding.Tests
python -m pytest tests/test_chronicle_source_package.py -q --disable-warningsviauv run: 124 passed.python -m pytest tests/test_chronicle_governance.py -q --disable-warningsviauv run: 2 passed.ruff checkandruff format --checkon edited Python files: passed.git diff --check: passed.