Skip to content
Dark MatterDark Matter
EnergyConcepts

DemandSpec

Structured capacity request. A buyer specifies requirements — capacity, jurisdiction, latency, chip class, compliance — and the rights engine matches against ComputeSlot inventory.

Overview

DMTR's existing IOI primitive expresses interest in a known position. DemandSpec inverts that: the buyer describes requirements — capacity, jurisdiction, latency, chip class, compliance, carbon profile — and asks which slots in inventory qualify.

matchDemand(spec, candidates) evaluates each candidate slot against the full rights-engine check set (BIS export controls, OFAC, RIGI, permit stack, water rights, indigenous consultation, data residency, interconnect priority) and returns a ranked list of results with conditional Verdicts attached.

Fields

PropertyTypeRequiredDescriptionExample
demand_idstringYesUnique identifier for the RFP.—
tenant_participant_idstringYesThe tenant requesting capacity (must exist in the Identity Graph).—
capacity_mw_minnumberYesMinimum capacity required, in MW.—
capacity_mw_maxnumberNoUpper bound, if any. Slots offering more than max are still surfaced but mw_offered is capped.—
duration_monthsintegerYesTerm length.—
earliest_energizationstringYesISO date — slot must be capable of energizing by this date.—
latency_classenumYesagnostic | ms_500 | ms_100 | ms_50 | ms_10. Latency-agnostic workloads (post-training, batch inference, thinking models) make LatAm and other long-haul geographies eligible.—
workload_classenumYestraining | post_training | batch_inference | interactive_inference | thinking | general_compute | crypto_mining | other.—
power_qualityenumYesbest_effort | interruptible | firm | two_nines | three_nines | four_nines | five_nines.—
chip_classenumNoany | hopper_or_better | blackwell_or_better | rubin_or_better | export_controlled_only_a800_h800 | trainium_or_better | tpu_v6_or_better. Drives BIS export-control evaluation.—
geography_filterobjectYesAllowed/excluded countries (ISO-2), allowed basins, max RTT to a target hub, target hub IATA.—
compliance_requirementsarrayNobis_export_clean, ofac_clean, itar_equivalent_clean, rigi_eligible, data_residency_country, low_water_only, no_indigenous_dispute, audited_carbon_class, sanctions_screened_supply_chain, five_eyes_only.—
pricing_envelopeobjectNoCeilings: capacity payment per MW-month, blended LCOE per MWh, total term value.—
carbon_classenumNoany | low_carbon | renewable_only | additional | removal.—
cfe_matching_requestenumNonone | annual | monthly | hourly_grid | hourly_site. Hyperscalers under 24/7 carbon-free-energy commitments (Google's 24/7 CFE target and Microsoft's 100/100/0 program, both 2030 commitments) typically require hourly_grid minimum.—
requires_decompositionbooleanNoIf true, partial-fit slots are surfaced (a 200 MW slot can contribute to an 800 MW demand).—
preferred_decomposition_block_mwnumberNoIf decomposition is required, the preferred block size for splits.—

Example: 1 GW LatAm batch-inference RFP

{
  "demand_id": "demand-hyperscaler-2027-q2-latam",
  "tenant_participant_id": "hyperscaler-tenant-001",
  "status": "open",
  "capacity_mw_min": 800,
  "capacity_mw_max": 1200,
  "duration_months": 60,
  "earliest_energization": "2027-06-01",
  "latency_class": "agnostic",
  "workload_class": "batch_inference",
  "power_quality": "interruptible",
  "chip_class": "blackwell_or_better",
  "geography_filter": {
    "allowed_countries": ["AR", "CL", "PY", "UY", "BR"],
    "excluded_countries": ["VE"]
  },
  "compliance_requirements": ["bis_export_clean", "ofac_clean", "rigi_eligible", "audited_carbon_class"],
  "carbon_class": "low_carbon",
  "requires_decomposition": true,
  "preferred_decomposition_block_mw": 100
}

The complete fixture is at packages/fixtures/energy/sample-demand-spec.json.

Matching

matchDemand(spec, slots, opts) returns one DemandMatchResult per qualifying slot, sorted by allowed first then by score descending:

import { matchDemand } from "@dmtr/energy/rights-engine";

const results = matchDemand(spec, store.listSlots(), {
  tenant: anthropic,
  tenantOfacScreenedAt: "2026-04-30",
  estimatedProjectValueUsd: 800_000_000,
});
// → [{ slot_id, score, allowed, conditional, missing_compliance, mw_offered, notes }, ...]

Score is the fraction of checks that returned pass (vs. fail/conditional/counsel_review). allowed mirrors the underlying Verdict's allowed flag — true unless any check returned fail.

When spec.requires_decomposition === true, slots smaller than capacity_mw_min are still surfaced as long as they meet the preferred_decomposition_block_mw threshold. When false, only slots ≥ capacity_mw_min qualify.

Rights-engine checks

matchDemand calls evaluateSlotForDemand for each candidate, running:

  1. Interconnect priority — queue position and approved capacity vs. requested
  2. Permit stack — required permits for the slot's site class
  3. Water draw — water rights vs. cooling design
  4. BIS export controls — chip class vs. destination country
  5. RIGI eligibility — Argentine RIGI certificate and project value threshold
  6. Indigenous consultation — ILO 169 / FPIC obligations where applicable
  7. Data residency — slot country vs. demand allow/exclude lists
  8. OFAC tenant — SDN screening (when a tenant participant is supplied)

Each check produces a CheckResult with status pass, fail, conditional, or counsel_review. The aggregated Verdict follows the same pattern as the core rights engine.

Edit this page on GitHub

Last reviewed: June 12, 2026

Was this page helpful?