Skip to content
Dark MatterDark Matter
EnergyRegulatory corpus

Corpus versioning

When to issue a new regulatory corpus snapshot, how to chain successors, and the legal-admissibility requirements that drive corpus immutability.

Why immutability matters

A Verdict issued in 2026-Q3 is a record of "what the rules said when this transfer was evaluated." Six months later — when a regulator asks the same question or a counterparty disputes the result — that Verdict has to be reproducible against the same rules. If the corpus is mutable, the same Verdict can yield different results before and after a code edit, and the audit trail becomes legally indefensible.

Stripe handles this with API versioning at the call site; ISDA handles it with Master Agreement supplement numbers; clinical trials handle it with protocol amendment numbers. DMTR handles it with regulatory_corpus_id pinned at evaluation time, against immutable snapshots.

Versioning rules

Format. <COUNTRY>@<YYYY-MM-DD>.<N> where <N> increments within the same date if multiple snapshots are issued in one day.

Immutability. Once a snapshot constant is committed and any Verdict references it, the constant must not be modified. Apparent typos in citations are treated as material — fix forward by issuing a new snapshot, not by editing the old one.

Chaining. New snapshots set supersedes: "<previous version>" so the chain is auditable. Older snapshots remain in CORPUS_REGISTRY indefinitely.

Effective dates. effective_from is when the snapshot's contents reflect the operative regulatory state in the jurisdiction (typically the publication date of the most recent material act it captures). effective_until is set on the previous snapshot when superseded.

What triggers a new snapshot

TriggerExample (Argentina)
New statute / decree / regulationDecreto 105/2026 expanding RIGI to onshore upstream
Derogation of an existing statuteDecreto 1083/2024 derogating federal Ley 26.160
Material threshold changeRIGI sector floor adjustment
New BCRA Comunicación material to FX flows"A" 8226 (cepo lift for personas humanas)
New BIS / OFAC / EAR posture material to chip classDiffusion Rule rescission (May 2025)
New open interpretive assumptionNew counsel-routed question added to open_assumptions
Counsel sign-off on an existing assumptioncurrent_position change from pending_counsel_opinion to counsel_confirmed / counsel_disconfirmed
New recognized provincial / regulatory authorityAddition of a new RegulatoryAuthority to the snapshot

What does not trigger a new snapshot: typo fixes (require a new snapshot), comment improvements (require a new snapshot), test additions (no snapshot effect). The discipline is rigid because the legal-admissibility floor demands it.

How a check pins to a snapshot

// In a check, the corpus is read at evaluation time:
import { lookupCorpus } from "@dmtr/energy/regulatory";

export function checkSomething(slot, opts) {
  const corpus = lookupCorpus(slot.jurisdiction.country, slot.regulatory_corpus_id);
  // ... read corpus.tax_stability_regimes, .open_assumptions, etc.
}

// In a Verdict, the corpus version is recorded:
{
  check: "rigi_eligibility",
  status: "pass",
  detail: "...",
  authority: "AR-RIGI",
  corpus_version: "AR@2026-05-06.1"
}

The corpus_version field on a CheckResult is the legally-operative anchor. Together with the rights-engine engine_version (a separate concept — see engine snapshots), a Verdict is fully reproducible at any point in the future.

Engine snapshots vs. corpus snapshots

Corpus snapshotEngine snapshot
What it capturesRegulatory state of a jurisdiction (statutes, authorities, programs, open questions)Behavior of the rights-engine code (which checks ran, with what thresholds, against what corpus)
GranularityPer countryRepo-wide
FormatTypeScript constantJSON snapshot in engine-snapshots/ directory
Trigger for new versionMaterial regulatory change in the jurisdictionMaterial code change in @dmtr/energy/rights-engine or @dmtr/core/rights-engine
Pinned viaPosition.regulatory_corpus_id, Verdict.corpus_versionVerdict.engine_version (release tag)

Both are required for full reproducibility — a Verdict needs to know which rules ran (engine_version) AND what the rules referenced (corpus_version).

Adding a new snapshot

// 1. Copy the previous snapshot to a new constant:
export const ARGENTINA_CORPUS_2026_07: RegulatoryCorpusSnapshot = {
  ...ARGENTINA_CORPUS_2026_05,
  corpus_version: "2026-07-15.1",
  effective_from: "2026-07-15",
  supersedes: "AR@2026-05-06.1",
  // ... apply material changes
};

// 2. Register it in `index.ts`:
export const CORPUS_REGISTRY = {
  "AR@2026-05-06.1": ARGENTINA_CORPUS_2026_05,
  "AR@2026-07-15.1": ARGENTINA_CORPUS_2026_07,
  // ...
};

// 3. Add `effective_until: "2026-07-15"` to the previous snapshot.
// 4. Open a PR with the diff visible — counsel reviews the delta.

Backfill

When a Position or CapacityContract is created without regulatory_corpus_id, the rights-engine treats it as referencing the latest snapshot for the slot's country. This is permissive for Developer Preview use but should be tightened to require explicit pinning before production-deal reliance.

Edit this page on GitHub

Last reviewed: May 6, 2026

Was this page helpful?