Extension Maintainer Guide

Technical guide for maintaining and contributing jurisdiction extensions.

5 min readLast updated: 16 April 2026

Overview#

This guide is for people who maintain existing INHERIT jurisdiction extensions — updating legal thresholds, verifying data against current legislation, and shepherding changes through review. If you are creating a new extension from scratch, see Building Extensions instead. Maintainers are responsible for keeping their extensions accurate, tested, and aligned with the core standard as both legislation and the INHERIT schemas evolve.

Extension Update Workflow#

Follow this process when updating an extension:

  1. Branch from main — create a feature branch (e.g. update/uk-iht-threshold-2027).
  2. Modify the schema — update the relevant properties in your extension’s JSON Schema file.
  3. Run the test suite — execute pnpm test and pnpm lint locally to catch errors early.
  4. Update the manifest — in your extension’s extension.json, bump the version field and set lastVerified to today’s date.
  5. Submit a pull request — include a clear description of what changed and cite the legislative source. CI runs metaschema validation automatically, so you will see immediate feedback on whether the schema is structurally valid.

Temporal Data Maintenance#

Many extension fields use the TemporalRule common type, which tracks values that change when legislation changes. A temporal rule has these key fields: value (the current amount or rule), effectiveFrom (when it takes effect), effectiveUntil (when it is superseded, or null if still current), status (e.g. enacted, bill_stage, announced), and predecessorValue (the previous value).

When legislation changes, maintainers must follow this procedure:

  1. Set effectiveUntil on the existing rule to the day before the new rule commences.
  2. Update value to the new amount or rule.
  3. Set effectiveFrom to the new effective date (the commencement date, not the date of royal assent or enactment).
  4. Move the old value into predecessorValue so consumers can compute deltas.
  5. Update lastVerified in the extension’s extension.json manifest.
  6. Add a legislativeReference citing the specific act and section.

Example: UK nil-rate band update. Suppose the nil-rate band increases from £325,000 to £350,000 from 6 April 2027 via Finance Act 2027 s.12. The maintainer would set value to 35000000 (minor units), effectiveFrom to "2027-04-06", predecessorValue to 32500000, status to "enacted", and legislativeReference to "Finance Act 2027 s.12". The previous rule’s effectiveUntil would be set to "2027-04-05".

Each extension in the registry has a legalReviewStatus field indicating the level of verification. There are three levels:

  • self_verified — The maintainer has checked the extension against published legislation and official government sources. This is the starting point for all core extensions. It means the data is believed to be accurate but has not been independently reviewed.
  • legislation_based — Primary legislation has been cited for every rule and threshold. Each temporal rule includes a legislativeReference field pointing to the specific act and section. This is a higher bar than self_verified because it requires traceable citations, not just a general check.
  • professionally_reviewed — A qualified legal professional (solicitor, advocate, notary, or equivalent) in the relevant jurisdiction has reviewed the extension and confirmed it accurately represents current law. This is the highest level of assurance.

To progress between levels, maintainers should add legislative citations to all temporal rules (to reach legislation_based) and then arrange for a qualified practitioner to review the extension (to reach professionally_reviewed). Update the legalReviewStatus field in extensions-registry.json when a new level is achieved.

CODEOWNERS Process#

Each extension directory is mapped to one or more maintainers in .github/CODEOWNERS. When a pull request touches files in an extension directory, the assigned maintainer is automatically added as a reviewer. This ensures that jurisdiction-specific changes are always reviewed by someone with domain knowledge.

To become a CODEOWNER for a jurisdiction, open an issue or discussion expressing your interest and demonstrating relevant expertise (legal practice in that jurisdiction, academic research, or prior contribution to the extension). The core team will add you to the CODEOWNERS file and grant you reviewer permissions. Existing maintainers can also nominate new co-maintainers by submitting a PR to update CODEOWNERS.

Graduation Criteria#

A community extension may be promoted to core status when it meets all of the following criteria:

  • Production use — at least one production implementation is using the extension to process real estate data.
  • Schema validation — the extension passes pnpm metaschema (valid JSON Schema 2020-12) and pnpm lint with no errors.
  • Test coverage — test fixtures include both valid and invalid examples, and all required fields are exercised.
  • Legal review — the legalReviewStatus is at least legislation_based, with legislative citations for all temporal rules.
  • Named maintainer — at least one person is listed in .github/CODEOWNERS for the extension directory.
  • Complete manifest — the extension.json file has all required fields populated, including dataProvenance, responsibleOrganisation, and lastVerified.

Testing Extensions#

Extensions must pass the following checks before a PR will be merged:

  • pnpm metaschema — validates that the schema is well-formed JSON Schema 2020-12 and conforms to the INHERIT dialect.
  • pnpm lint — checks for style and structural issues across the schema and manifest.
  • pnpm test — runs test fixtures against the schema. Every extension must have at least one valid example and one invalid example in the test directory.
  • Manual validation — generate a complete INHERIT document that includes your extension data, then validate it with the Sourcemeta CLI (jsonschema validate). This catches integration issues that unit tests may miss, such as $ref resolution failures or conflicts with core schema properties.