Editorial methodology
How we keep the VAT numbers right
Every rate, threshold and rule VATLY shows comes from a typed row in a maintained rules engine. Each row records an HMRC source URL, the date the figure first applied, and the date a human reviewer last verified it. A daily background job flags any row not reviewed in 90 days. This page documents that process in full.
1. Source provenance — every figure is traceable
Each rate row in packages/rules-engine is a typed record with the following fields:
- value — the rate or threshold itself, stored as an integer (basis points for rates, pence for cash).
- source_url — a single canonical HMRC page (usually
gov.uk) that defines the figure. - applies_from — UK tax-year-aware effective date (e.g.
2025-04-06). - applies_to — null when current; populated when superseded.
- last_reviewed_at — the last time a human reviewer verified the row against the source.
- reviewer_id — who did the review.
- notes — exceptions, caveats, or HMRC's own wording where it materially clarifies.
When a calculator renders a rate, the source URL and "last reviewed" date are shown inline. Compare this with the typical UK VAT calculator, which usually shows a single static rate with no source link at all.
2. Editorial review cadence — 90-day stale-rule audit
A daily cron runs at 06:00 UTC. It scans the rules-engine seed and writes an audit_log entry with severity governance.stale_rule for any row whose last_reviewed_at is older than 90 days. Those entries land in an editor's queue. The corresponding fix is either:
- Re-verify the figure against the source URL and bump
last_reviewed_at; or - Update the figure (and the source URL if HMRC has moved the page) and bump
last_reviewed_at; or - Supersede the row by setting
applies_toand inserting a new row with the updated value.
Code-only changes never bump last_reviewed_at. Bots can tell the difference between an editorial change and a refactor; trust degrades fast if the date lies. This is policed by a unit test in the rules-engine package.
3. Severity ladder — what gets reviewed when
Not every audit-log entry needs the same response time. The severity values are defined in docs/EDITORIAL_WORKFLOW.md:
- governance.stale_rule — review within 14 days.
- governance.missing_provenance — a row is missing one or more of the mandatory fields. Fix within 7 days.
- governance.value_disputed — a user-reported correction or an internal find. Fix within 48 hours.
- governance.figure_changed_at_source — HMRC has updated the underlying figure. Same-day update.
4. Rounding policy — integer pence, banker's rounding
All money on VATLY is stored and computed as integer pence. Display formatting uses a typed Pence brand to make it impossible to add pounds and pence by accident. Where a rounding decision is required, the calculator uses banker's rounding (round-half-to-even) — the same convention HMRC uses in its own published examples for VAT amounts.
The full money policy, including overflow guards, parse rules, and the thin-space pound-symbol formatting, lives in docs/MONEY_POLICY.md.
5. Tax-year boundary — Europe/London, not UTC
UK tax years run 6 April to 5 April. To decide which tax year applies to a given calculation, VATLY converts to a London-local date before comparing against rule applies_from / applies_to. Without this, the tax year would flip an hour late during BST. This is tested explicitly with cases like "23:30 UTC on 5 April during BST" to lock the behaviour.
6. Testing — golden cases against HMRC examples
The @vatly/calculations package ships 33 hand-verified golden tests sourced from HMRC's own published worked examples. They include:
- 9 UK VAT cases (Standard Scheme + Flat Rate Scheme + reverse VAT)
- 6 PAYE/income-tax cases (UK and Scotland rates, with personal-allowance taper)
- 4 NHS pension tier lookups
- Property-style sweeps for net + VAT = gross over £0–£200,000
- Threshold-status monotonicity tests
New calculators ship with a minimum of five hand-verified goldens before going live. Tests run on every push and block deploys on failure.
7. Public correction path
If you spot a figure you believe is wrong, email hello@vatly.uk with the calculator URL, the figure you saw, what you believe the correct value should be, and (ideally) an HMRC link. Disputed values are logged as governance.value_disputed with a 48-hour SLA. We will reply with the resolution, including a link to the audit-log entry.
8. What we will not do
For trust reasons we deliberately avoid:
- Pseudo-precision claims like "save £332/year" without transparent methodology.
- SEO listicles ("13 mistakes that cost thousands") on product pages — useful as content, dishonest framing on a calculator.
- Embedding third-party analytics on calculator pages (PostHog is opt-in and only inside the signed-in app, never on the public calculators).
- Stale third-party content libraries — every figure on VATLY is maintained by us against an HMRC source, not bought in.