WAI Extension: Energy Methods
Mirrored from the canonical text at commit c5e7133e ().
Status: Draft. Registers no capability. Maps WAI’s signed energy records onto the methods the media and ICT industry uses to measure and report energy and emissions, method by method: what quantity each asks for, over what functional unit and boundary, which fields of which WAI record supply it and under what conditions, where a WAI record supplies more (a signed reading that names its counter, its span and its acquisition class), and where it supplies nothing. A field WAI cannot supply is stated as not supplied, with the reason; nothing is estimated to fill it. It defines two figures of WAI’s own, energy per viewing hour and per gigabyte delivered, with their exact numerators and denominators (§5); a signed, location-based factor table an operator supplies, the only way carbon enters (§6); and an export, a signed document that states each method’s report form from a set of signed records and a factor table, every figure naming the records it rests on, a partial total marked partial and no two classes ever summed (§7, §8), with its verification (§9). The reference implementation is the
energy_methodsmodule ofwai-rs(featureenergy_methods); the corpus islive-conformance/energy-methods/, written bywai_energy_methods_vectors, and its second implementation islive-conformance/energy_methods_verify.py. Keywords MUST, MUST NOT, SHOULD, MAY are RFC 2119/8174.Texts read for this revision, each the revision named (decision D43 names each file read by the first and last eight digits of its SHA-256):
- ITU-T L.1333 (09/2022), edition 1.0, Carbon data intensity for network energy performance monitoring, whole.
- ITU-T L.1480 (07/2025), edition 2.0, Enabling the Net Zero transition – Assessing how the use of information and communication technology solutions impacts greenhouse gas emissions of other sectors: clauses 1 to 14 and Annex A; its appendices in part.
- GHG Protocol Scope 2 Guidance (2015), as published with its electronic corrections to April 2025: chapters 4 to 7. A revision was in public consultation from 2025-10-20 to 2026-01-31 and is not yet a standard; this text maps the 2015 guidance.
- GHG Protocol ICT Sector Guidance (July 2017), built on the Product Life Cycle Standard: chapters 1, 2, 4 and 6, and the Product Standard’s §13.2 for the report.
- ISO/IEC 21031:2024, edition 1.0: its text is sold, and the publisher’s page refused an unattended fetch, so it was not read. The Green Software Foundation’s public SCI specification was read in its versions 1.0.0 (which the Foundation states became the ISO standard) and 1.1.0.
- The Green Software Foundation’s SCI for AI, ratified for public review 2025-12-17: the ratification-era text and the later main and development texts of 2026.
- The DIMPACT methodology, version 1.0 (October 2022), whole, with the public papers that describe its model. Its tool and input tables are given to members only and were not read.
- Greening of Streaming: its nine public publications (May 2023 to February 2026). It has published no reporting format; its members’ area was not read.
- AFNOR SPEC 2314 (June 2024): its text is behind a registration form and was not read; the public summary its government sponsor published was.
- Blauer Engel DE-UZ 215, Ressourcen- und energieeffiziente Softwareprodukte, edition January 2020, version 6 (07/2026), with its annexes, whole.
- UNE 0086:2025 (edition 2025-10-08, corrected 2026-07-29): its text is reached only through a store’s checkout and was not read; its public scope and the sponsor’s release were.
- CEN/CLC/TR 18145:2025: sold, not read; its public scope pages were.
1. Scope
In scope: what WAI’s energy records supply to each method (§3, §8); the rules every statement of a WAI figure under a method follows (§4); WAI’s own derived figures (§5); the factor table (§6); the export, its forms and their CSV (§7, §8); its verification (§9).
Out of scope: how a figure is measured, which energy-measurement governs; a method’s own rules for what an organisation must report; and any statement that a method is satisfied. An export is a record of what signed records state, in the fields a method names. It is not a submission under any method or regime and claims to satisfy none: how an organisation enters a figure in its own inventory, and what it adds from other sources, is its own. An export compares nothing with anything: it states no baseline, no saving and no avoided emission, and a field a method defines for one of those is stated as not supplied (§4, rule 7).
Relationship to other documents:
- energy-measurement. Every figure an export states carries the acquisition class of its §2, and its rules hold: an unmetered figure is not zero (§2), a class says what backs the uncertainty and not where the counter sits (§2.2), a figure is scoped to what its counter reports (§5), and an estimate is presented as one (§9.4, §9.5).
- energy-binding §4. Carbon is a modelled quantity beside the measured joules, never in their place, and is never derived from a grid factor and presented as measured. §6 here is the one way an export states carbon.
- live-metering, sink-energy and task-fidelity §5. The records an export reads (§3.1), each verified by its own extension’s verifier.
- receipt-ledger §5.2. The registry of record kinds. An export
names records by the kinds registered there: 1 (
WMR1), 2 (WMH1), and the kinds this extension registers there, 28 (a sink session receipt), 29 (a sink segment receipt), 30 (asplit-computationclaim) and 31 (a factor table, §6). - receipt-ledger §6.6. An export’s energy rows follow the same
rule as an invoice’s: one row per class,
max_ppmthe largest declared relative uncertainty of tags 4 and 5, whole or partial.
2. Terms
- Figure: one energy figure of one record, in microjoules, with its acquisition class (energy-measurement §2); or the unmetered marker, which is not a figure of zero joules.
- Class:
CalibratedInstrument(tag 5),OnChipCounter(4),ModelBased(2) orEstimator(3) (energy-measurement §2.7).HwShuntis never a class of a figure an export states: every record an export reads refuses it (energy-measurement §2.6). - Component: where in a delivery a figure was spent (§3.1):
delivery_relay,delivery_compositor,delivery_ingest,device_decode,device_display,computation_head,computation_tail, in that order. - Coverage:
wholeorpartial(energy-binding §4). - Span: the instants a figure was spent over,
[from_us, to_us), in microseconds since 1970-01-01T00:00:00Z, ignoring leap seconds. - Region: a label of 1 to 64 characters from
a–z,0–9and-, neither first nor last a hyphen, naming a grid area as the operator’s factor table names it. - Scope of a factor:
generation(the emissions of generating the electricity only) orlifecycle(generation with the fuel supply chain and transmission and distribution losses). - Source: the records an export reads together under one head (§7.1).
- Reference to a record:
{ "kind": <record kind>, "id": <64 hex digits> }, the kind from receipt-ledger §5.2 and the identity its own extension defines. - JCS: RFC 8785. Hexadecimal is lowercase. A quantity is a non-negative integer
written as a JSON string of decimal digits with no leading zero (
"0"for zero); every other number in a record of this extension is a JSON integer from 0 to 2⁵³ − 1.⌊x⌋is the floor, and every division is exact integer arithmetic.
3. What the records supply
3.1 The records an export reads
| source | record | component of each figure | figure, class | span | activity units |
|---|---|---|---|---|---|
room | each per-hop session record WMH1 a room-session receipt WMR1 names (live-metering §3.1, §4.1) | role 1 delivery_relay, 2 delivery_compositor, 3 delivery_ingest | the record’s joules and class: the hop’s own energy over its span, under its counter’s scope (task or package, live-metering §8) | the record’s start and end, plus the room’s t0 (live-events §2): a span on UTC | from the receipt: subscriber_us by layer class and sessions (live-metering §4.4); from each record’s ledger: each entry’s bytes_in and bytes_out (live-metering §3.4) |
sink | a sink session receipt and its segment receipts (sink-energy §5, §6) | its hop of role 3 device_decode; of role 4 device_display | that hop entry’s figure and class (sink-energy §6.3) | none: the records state no instant | media_us and presented_us (sink-energy §6.1) |
split | the two split-computation claims of one computation (task-fidelity §5) | the head computation_head, the tail computation_tail | each claim’s energy, null being the unmetered marker | none: a claim states when it was issued, not when the work ran | one computation per source |
A sink session receipt’s origin and relay entries are not figures of an export. Each
restates a hop’s own record (sink-energy §6.4), which reaches an export as that hop’s figure
in a room source, once.
Where a WAI record supplies more than a method asks: every figure names the class that backs its uncertainty, and for the hardware classes a declared standard uncertainty with its window (energy-measurement §2.3); a hop’s figure names the hop’s key and the span it covers, and is signed by that key; a sink’s decode figure names its counter profile and the fabrics it covers (energy-measurement §9); a measured figure was sealed only from a live rail and a bracket whose ratio met energy-measurement §4. No method this text maps asks for any of these, and the forms carry the class and the largest declared uncertainty beside every figure so that none is lost.
3.2 Records an export of this revision does not read
These carry figures a method could use; this revision maps them and its export does not read them. A later revision that reads one adds it to §3.1.
- An energy binding (energy-binding):
microjoules,acquisition,coverage,workUnitsandmethodfor one reconstruction. No Ed25519 key signs it, so an export, which cites what its signer signed, does not read it. - JWP object and group receipts and
energyclaims: a figure per object, its class in the object’s leaf or in the claim (energy-measurement §1). They supply a per-object functional unit (an image, a segment, a frame) for the methods that state one. - OER/2 receipts (oer-receipts §3.1): a job’s
energy.joules_totalwith its class in minor version 1, and the evidential grade of its §2. They supply a data centre’s processing energy per job. - An invoice’s energy rows (receipt-ledger §6.6): per scope and class, already summed. An export reads the records the rows were summed from instead.
- delivery-telemetry observations carry no energy figure and are signed by nobody (its §1). They supply nothing here.
3.3 What no WAI record supplies
No WAI record states, and an export therefore never states:
- Embodied emissions: raw material, manufacture, transport, installation, end of life.
- The energy of networks between hops: core, metro and access networks, a home gateway. A hop’s figure is its own (live-metering §4.6: an attributed share says nothing of what the network between hops spent), and a sink reads no network’s energy (sink-energy §1).
- Site energy: cooling, power feeding and the building around a hop. A figure is scoped to its counter (energy-measurement §5).
- Contractual instruments: certificates, power purchase agreements, supplier rates. An export states no market-based figure.
- Where a sink is, or when it decoded: a sink’s records name no place and no instant, and WAI texts say nothing of how an operator identifies a person.
- Training energy, water, standby energy, and any counterfactual (a reference scenario, a saving, an avoided emission).
4. Rules every export follows
- Classes are never summed. Every energy, carbon or derived figure an export states is the figures of one class. A method field that its method defines as one number over all of a component’s energy is stated once per class present, each marked partial where any other class or any unmetered figure is present. A total of two classes is neither a counter reading nor a model’s output (live-metering §4.5).
- Unmetered stays unmetered. An unmetered figure is counted, in no row, and never written as zero joules, zero carbon or zero intensity (energy-measurement §2).
- Partial is marked partial. A row is
wholeonly where every figure of its component is of its class and none is unmetered; otherwisepartial, and a partial row MUST NOT be presented as the component’s energy. A form field issuppliedonly on the same condition over every component it reads, andpartialotherwise. - Nothing is estimated to fill a gap. A field no record supplies is
not_supplied, with its reason (§8.1). No default, typical value, intensity per byte or power model stands in for a figure, and no figure of one class stands in for another. - Every figure names its records. Each line, row and field names the records it rests on, by reference (§2), so a reader can recompute it.
- Carbon only from the operator’s signed, location-based factor table (§6), each factor naming its source by digest; never from a built-in factor. Carbon is a model beside the measured joules (energy-binding §4) and is always stated beside them.
- No comparison. An export states no baseline, no saving, no avoided emission and no claim about any method’s labels; it compares no figure with any other party’s.
- Estimates stay apart. An
Estimatorfigure is presented as an estimate. A display’s figure is its own component and is never added to a decode’s (energy-measurement §9.5).
5. WAI’s derived figures: per viewing hour and per gigabyte delivered
5.1 Viewing time
The viewing time V of an export is the sum, over its room sources, of each receipt’s
subscriber_us for layer classes 0 to 7 (live-metering §3.3, §4.4): the
subscriber-microseconds during which a subscriber session held a media track of the room. It
is the receipt’s own unit, recomputed by the receipt’s verifier from the per-hop records
(live-metering §5.1 step 8). Layer class 8, a session subscribed to tracks of the room and to
none of its media tracks, views nothing: its time is stated apart as events_only_us and is
in no denominator. A viewing hour is 3.6 × 10⁹ µs of V.
5.2 Bytes delivered
The bytes delivered D of an export is the sum, over its room sources, over every
per-hop record each receipt names, of its ledger entries’ bytes_out
(live-metering §3.4): the payload bytes the hops sent the room’s
sessions. In a receipt of version 2 it is the receipt’s own bytes_out unit (live-metering
§4.4); in a receipt of version 1 it is the same sum, read from the ledgers whose roots the
records sign. Bytes a hop sent another hop over a hop link are in no ledger
(live-metering §3.10), so a byte is counted once, at the hop that delivered it to a session.
A gigabyte is 10⁹ bytes.
5.3 The figures
For each class c among the figures of the export’s delivery_relay,
delivery_compositor and delivery_ingest components, let J_c be the sum of their
figures of class c, in microjoules. Then:
per viewing hour, class c = ⌊J_c · 3 600 000 000 / V⌋ µJ per viewing hour
per gigabyte delivered, c = ⌊J_c · 1 000 000 000 / D⌋ µJ per gigabyte
each stated with its numerator J_c and its denominator V or D, and none at all where
the denominator is 0. A figure is whole only where every figure of the three components is
of class c and none is unmetered; otherwise it is partial, and is the class-c hops’
energy over the delivery’s viewing time or bytes, not the delivery’s energy per hour or per
gigabyte.
5.4 What they are not
- They are the hops’ own energy over their spans, which is largely what running a hop costs whatever it carries, divided by what the hops delivered. They are not the marginal energy of one more viewer or one more byte, and dividing does not make a hop’s energy proportional to either (live-metering §4.6).
- They count no network between hops, no sink and no display (§3.3). A reader MUST NOT present either figure as the energy of watching for an hour or of moving a gigabyte end to end.
- They are one deployment’s figures over its own records, and an export states no comparison of them with anyone’s (§4, rule 7).
6. The factor table
6.1 The record
A factor table is a JSON object (RFC 8259) an operator signs: where its hops’ figures were
read (sites), and each grid area’s location-based emission factor over a period
(factors), each naming the publication it was taken from by its SHA-256.
| member | type | meaning |
|---|---|---|
wai_energy_factors | integer | 1 |
signer | 32 B hex | the operator’s key |
basis | string | "location-based": a grid’s average where and when the energy was used |
sites | array | each { "key": 32 B hex, "region": region, "from_us": integer, "to_us": integer }: the figures signed by key over [from_us, to_us) were read in region |
factors | array | each { "region": region, "scope": "generation" or "lifecycle", "from_us": integer, "to_us": integer, "mg_co2e_per_kwh": integer, "source": 32 B hex, "source_title": string } |
sig | 64 B hex | §6.2 |
Its body is the object without sig. It is signed with Ed25519 (RFC 8032) by signer
over wai:energy-factors\x01 ‖ JCS(body), verified as WAI verifies every signature (SPEC
§7 Signatures). Its identity, record kind 31, is
SHA-256(wai:energy-factors-id\x01 ‖ JCS(body) ‖ signature bytes).
6.2 Rules
A table is refused, factors_invalid, unless: it has exactly these members, of these types;
basis is location-based; it has at least one factor; each factor’s region is a region
(§2), its scope one of the two, from_us < to_us, mg_co2e_per_kwh at least 1, source
64 hexadecimal digits and source_title 1 to 200 characters, not all of them a space, a
tab, a line feed or a carriage return; no two
factors of one region and one scope have periods that overlap; each site’s key is 32 B hex,
its region a region and from_us < to_us; no two sites of one key overlap; and its
signature verifies.
A factor of zero states no factor. A factor without a source cannot be fetched and checked. A market-based factor rests on instruments no WAI record carries, so a table states none.
6.3 A figure’s carbon
For a figure and a scope, its carbon is the first of these that applies:
- no factor table is given: none,
no_factors; - the figure is unmetered: none,
unmetered; - the figure has no span: none,
no_span; - no site of the figure’s signer overlaps its span: none,
no_site; a site overlaps it but none holds the whole span: none,span_split; - of the site that holds the span, no factor of its region and the scope overlaps the span:
none,
no_factor; one overlaps it but none holds the whole span: none,span_split; - otherwise the factor that holds it gives
⌊joules_micro · mg_co2e_per_kwh / 3 600 000 000⌋micrograms of CO2e, and is named byk, its place infactorscounted from 0.
A site or factor overlaps a span when its from_us is below the span’s to_us and the
span’s from_us below its to_us, and holds it when its from_us is at most the span’s
and its to_us at least the span’s. A figure whose span crosses two periods has no carbon: dividing it between
them would assume a draw constant over the span, which no record states.
7. The export
An export is a JSON object signed by its exporter. Its body is the object without sig;
it is signed over wai:energy-export\x01 ‖ JCS(body), and its identity is
SHA-256(wai:energy-export-id\x01 ‖ JCS(body) ‖ signature bytes).
| member | type | meaning |
|---|---|---|
wai_energy_export | integer | 1 |
signer | 32 B hex | the exporter’s key |
sources | array | each source’s kind and head, in the order given (§7.1) |
factors | reference or null | the factor table, kind 31 |
period | object or null | { "from_us", "to_us" }: the least from_us and greatest to_us of the figures’ spans; null where no figure has one |
figures | array | the lines (§7.2) |
units | array | §7.3 |
energy, unmetered, carbon, derived | arrays | §7.3 |
forms | array | §8 |
sig | 64 B hex |
7.1 Sources
An export is computed from a list of sources, each a JSON object whose kind names it:
kind | members | head | verified as |
|---|---|---|---|
room | receipt-ledger §5.1’s room source, exactly | the receipt, kind 1 | live-metering §5.1 |
sink | session (the session receipt), segments (its segment receipts), tables (the decode tables its table segments name), hops (the hop records its entries name, hexadecimal) | the session receipt, kind 28 | sink-energy §7: the session against its segments and hops |
split | head, tail (each the text of a split-computation claim), held ({ "head", "tail" }, each a parameter set’s digest or null) | the head claim, kind 30 | jwp-receipts §3.1 steps 1 to 5 for each claim, then task-fidelity §5.3 for the pair |
An export’s sources member lists { "kind", "head" } for each, the head a reference.
A source that is not such an object, whose kind is none of these or whose members are not
exactly its kind’s, each of its form, is source_malformed. A sink source gives the session’s
segment receipts, at least one, each an object as its session is; one that gives none is
source_malformed. A split source’s head is the head: a pair that composes with its tail
given as head is refused, source_refused with split_side_mismatch. A source one of whose
spans ends past 2⁵³ − 1, or one of whose declared uncertainties is past it, cannot be stated
and is source_malformed.
7.2 Figures
Each figure of each source is one line, the sources in the order given; in a room source
the hop entries in the receipt’s order; in a sink source its decode, then its display
where the session has one; in a split source the head, then the tail.
| member | meaning |
|---|---|
component | §3.1 |
record | the figure’s own record: the WMH1 (kind 2), the session receipt (kind 28), the claim (kind 30) |
cites | the records it rests on: for a hop, its record and the receipt; for a decode, the session receipt and each segment receipt in order; for a display, the session receipt; for a half, its claim and the other half’s |
signer | the key that signed the figure: the hop, the sink, the half’s signer |
span | { "from_us", "to_us" } or null (§3.1) |
class | its class label, or null for the unmetered marker |
uj | its microjoules, a quantity, or null for the unmetered marker |
relative_ppm, window_us | its declared uncertainty, integers, for tags 4 and 5; otherwise null |
delivered_bytes, traffic_bytes | for a hop: the sums of its ledger’s bytes_out and of its bytes_in and bytes_out, quantities; otherwise null |
carbon | { "generation": c, "lifecycle": c }, each c either { "factor": k, "ug": quantity } or { "why": reason } (§6.3) |
A source reads its head and the records its figures are stated from: a room source its
receipt and each per-hop record the receipt names; a sink source its session receipt and each
segment receipt; a split source its two claims. A record that two sources read, or one source
twice, is refused, record_duplicate, at the later source: a figure is counted once. The hop
records a sink source gives for its origin and relay entries are not read in this sense
(§3.1).
7.3 Rows
units: one row per unit, in this order, each{ "unit", "value", "cites" },valuea quantity andcitesthe heads of the sources it is summed over:viewing_us(V, §5.1),events_only_us,sessions,delivered_bytes(D, §5.2) andtraffic_bytes(every ledger entry’sbytes_inandbytes_out) over theroomsources;media_usandpresented_usover thesinksources;computations, the number ofsplitsources, over them.energy: for each component in order, for each class among its metered figures in ascending tag:{ "component", "class", "figures", "uj", "max_ppm", "coverage", "delivered_bytes", "traffic_bytes", "cites" }: the figures’ count, an integer, and their sum, a quantity; the largestrelative_ppmamong them for tags 4 and 5, 0 for tags 2 and 3, an integer;wholeorpartialby §4 rule 3; for adelivery_*component the sums of its figures’ bytes, quantities, otherwisenull; and each figure’srecordin line order.unmetered: for each component with an unmetered figure, in component order,{ "component", "figures", "cites" }: their count and each one’srecord.carbon: for each energy row and each scope,generationthenlifecycle:{ "component", "class", "scope", "coverage", "ug", "why", "cites" }. Where every figure of the row has carbon at the scope,ugis their sum andwhyisnull; otherwiseugisnullandwhyis the reason of the first figure, in line order, that has none. Its coverage is the energy row’s, and itscitesthe energy row’s, then the factor table’s reference where one is given.derived: for each class among thedelivery_*components’ metered figures, in ascending tag, two rows,per_viewing_hourthenper_gigabyte_delivered:{ "figure", "class", "coverage", "uj", "over", "value_uj", "cites" },ujitsJ_c,overitsVorD,value_uj§5.3’s figure ornullwhereoveris 0, andcitesthe figures’ records.
7.4 The CSV
An export’s CSV is its forms, one line per field, under the header
method,field,class,status,value,unit,reason,rests_on: each field’s members in that order,
null written as nothing, rests_on joined by single spaces. A value holding a comma, a
double quote or a line feed is enclosed in double quotes, each double quote in it doubled
(RFC 4180). Lines end with a line feed, the last too. The CSV is not signed: it is a
rendering of the signed forms, and a verifier recomputes it.
8. The methods
Each method’s form is { "method", "revision", "not_covered", "fields" }: the method’s
name, the text read, what of the method this revision could not read (null where it read
the text), each exactly as this table writes it, and its fields in the order of its section’s
table. An export states the twelve forms in this order.
method | revision | not_covered |
|---|---|---|
itu-t-l1333 | ITU-T L.1333 (09/2022), edition 1.0 | null |
itu-t-l1480 | ITU-T L.1480 (07/2025), edition 2.0 | null |
ghg-scope2 | GHG Protocol Scope 2 Guidance (2015), corrections to April 2025 | null |
ghg-ict | GHG Protocol ICT Sector Guidance (July 2017) | null |
iso-iec-21031 | SCI specification 1.0.0 and 1.1.0 (ISO/IEC 21031:2024 edition 1.0) | the ISO/IEC text, which was not read |
sci-ai | SCI for AI, ratified 2025-12-17 | null |
dimpact | DIMPACT methodology 1.0 (October 2022) | the tool and its input tables, which were not read |
greening-of-streaming | Greening of Streaming public publications, May 2023 to February 2026 | members' documents, which were not read |
afnor-spec-2314 | AFNOR SPEC 2314 (June 2024), public summary | the text, which was not read |
de-uz-215 | DE-UZ 215, January 2020 edition, version 6 (07/2026) | null |
une-0086 | UNE 0086:2025, public scope | the text, which was not read |
cen-clc-tr-18145 | CEN/CLC/TR 18145:2025, public scope | the text, which was not read |
8.1 Fields
Each field is { "field", "class", "status", "value", "unit", "reason", "rests_on" }.
status is supplied, partial or not_supplied; a field that is not supplied has value
null and a reason, and one that is has reason null. value is a string or null, and class a class label or null. rests_on names, as
strings, the rows it is computed from: energy:<component>:<class>, unmetered:<component>,
carbon:<component>:<class>:<scope>, unit:<unit>, period, and factors for the factor
table.
A field’s group is the components it reads. A class is present in a group when one of
its metered figures has it; the per-class quantities state one field for each present class,
in ascending tag, and where none is present, one field of class null, not_supplied, with
the reason no_figure where the group has no figure at all and unmetered where all its
figures are unmetered (rests_on its unmetered rows). A per-class field’s energy rows are
the rows energy:<component>:<class> of its group’s components that have one, in component
order. Its quantity is one of:
| quantity | what it states |
|---|---|
E(group, unit) | per class: the sum of the class’s figures, in unit. Rests on its energy rows. |
C(group, scope, unit) | per class: the sum of the carbon of the class’s figures at scope where each has carbon; otherwise not_supplied with the reason of the first, in line order, that has none. Rests on the rows carbon:<component>:<class>:<scope> of its energy rows. |
I(group, over, m, unit) | per class: the class’s microjoules × m over the unit row over, in unit; not_supplied, no_denominator, where that row is 0. Rests on its energy rows and unit:<over>. |
CI(group, scope, over, m, unit) | per class: as C, then the carbon × m over over: the unit row over, or, for class_traffic, the summed traffic_bytes of its energy rows; no_denominator where that is 0. Rests on its carbon rows and unit:<over>, or for class_traffic its carbon rows and energy rows. |
U(unit, to) | the unit row in to, class null, supplied; not_supplied, no_figure, where no source of the kinds the row is summed over is given. Rests on unit:<unit>. |
B(group, to) | the summed traffic_bytes of every figure of the group, metered or not, in to, class null, supplied; not_supplied, no_figure, resting on nothing, where the group has no figure. Rests on the group’s energy rows in their order, then its unmetered rows. |
D | the export’s period, to_us − from_us, in days, class null, supplied; not_supplied, no_span, where it is null. Rests on period. |
F(group, scope) | the factors that give the group’s figures their carbon at scope, each once, in the table’s order, each written sha256:<source> <source_title> (<region>, <scope>, from <from_us> to <to_us>, <mg> mg CO2e/kWh), joined by ; , class null, supplied, resting on factors. Where none does: no_figure or unmetered as above, and otherwise the reason of the group’s first metered figure in line order, resting on factors where a table is given and on nothing where none is. |
R(group) | the regions of the sites that hold the spans of the group’s figures, each once, sorted, joined by , , class null, supplied, resting on factors. Where none does: no_factors without a table, no_span where no figure of the group has a span, and no_site otherwise, resting on factors where a table is given and on nothing where none is. |
Q(group, words) | per class: a word for the class, by words, the first for tags 4 and 5 and the second for tags 2 and 3: primary or modelled; primary or secondary; measured or estimated; or, for class label, the class’s label. Rests on its energy rows. |
P(group) | per class: for tags 4 and 5 the largest max_ppm of its energy rows in percent; for tags 2 and 3 not_supplied, no_uncertainty. Rests on its energy rows. |
T(text) | the text, class null, supplied, resting on nothing. |
N(reason) | class null, not_supplied, reason, resting on nothing. |
The status of an E, C, I, CI, Q or P field that states a value is supplied where
every figure of the group is of its class and none is unmetered, and partial otherwise. A
field’s unit is the unit it is stated in (null for Q, R, F, T and N), also where
it is not supplied. A value is a decimal of the unit’s places, floored, with no other
rounding: ⌊n · 10^places / divisor⌋ written with its integer part, at least one digit, a
point, and exactly places digits:
| unit | from | divisor | places |
|---|---|---|---|
Wh | µJ | 3 600 000 000 | 12 |
kWh | µJ | 3 600 000 000 000 | 15 |
MWh | µJ | 3 600 000 000 000 000 | 18 |
gCO2e | µg | 1 000 000 | 6 |
kgCO2e | µg | 1 000 000 000 | 9 |
tCO2e | µg | 1 000 000 000 000 | 12 |
GB | bytes | 1 000 000 000 | 9 |
TB | bytes | 2⁴⁰ | 12 |
h | µs | 3 600 000 000 | 9 |
days | µs | 86 400 000 000 | 6 |
% | ppm | 10 000 | 4 |
An intensity is the decimal of its numerator × m over the product of its denominator and
its numerator unit’s divisor, at that unit’s places: kWh per viewing hour, kWh per GB
and kWh per inference at the places of kWh, over 3 600 000 000 000 times the
denominator; gCO2e per viewing hour and gCO2e per GB at the places of gCO2e; and
kgCO2e/TB, with m 2⁴⁰, at the places of kgCO2e, a terabyte being 2⁴⁰ bytes as ITU-T
L.1333 clause 8 counts it. The floor is taken once, of the whole quotient, in exact integers
of any size.
The reasons a field states: no_figure, unmetered, no_record (no WAI record states the
quantity, §3.3), embodied, market_based, outside_records (a scenario, an effect or a base
year no record states), no_claim (§4 rule 7), no_factors, no_site, no_span,
no_factor, span_split, no_denominator, no_uncertainty, average_factor (§8.6).
The groups: delivery is delivery_relay, delivery_compositor, delivery_ingest;
data centre is delivery_compositor, delivery_ingest, computation_head; user
premises is device_decode, computation_tail; computation is computation_head,
computation_tail; operational is every component but device_display.
A split computation’s head is the origin side and its tail the sink side (task-fidelity §5: the work partition between an origin and a sink); that is where a form places them.
8.2 ITU-T L.1333
itu-t-l1333. The KPI is NCIe, network carbon intensity energy (clause 8): the GHG
emissions of the electricity of every site of a network, its supporting equipment included
(clause 6), over one year (clause 9), per terabyte of the traffic at the network’s user
interface (clause 9). WAI meters no equipment of a network in its clause 7 sense. What it
supplies is a relay hop’s own energy, a part of the energy of the site it runs in, and the
bytes that hop exchanged with the sessions it served, which are traffic at the hop’s user
interface. The NCIe it states is that of its relays alone, and partial against the clause.
| field | quantity |
|---|---|
E_j: relay hops | E(delivery_relay, kWh) |
E_j: site and supporting equipment | N(no_record) |
E_j: network equipment (access, transport, mobile) | N(no_record) |
EF_j: location-based | F(delivery_relay, lifecycle) |
EF_j: market-based | N(market_based) |
Data traffic_j: relay hops at the user interface | B(delivery_relay, TB) |
NCIe: relay hops | CI(delivery_relay, lifecycle, class_traffic, 2⁴⁰, kgCO2e/TB) |
Measurement duration | D |
Clause 8 asks factors that include the supply chain and distribution losses, so the form
uses factors of scope lifecycle. The KPI’s period is one year; the form states the
export’s.
8.3 ITU-T L.1480
itu-t-l1480. The assessment asks the net second-order effect of an ICT solution against a
reference scenario (clause 11), its first-order effects in four parts (11.3.7.1.2) over the
life cycle (11.2.4), and a statement of data quality distinguishing primary data, secondary
data and estimates (11.4.2). WAI supplies the use stage of parts 1 to 3 where its records
meter them, and none of the rest. Since higher-order effects are never supplied, the study’s
result is initial guidance (11.5).
| field | quantity |
|---|---|
First-order, part 1 (user premises), use stage energy | E(user premises, kWh) |
First-order, part 1, display (estimate) | E(device_display, kWh) |
First-order, part 1, use stage GHG | C(user premises, lifecycle, kgCO2e) |
First-order, part 2 (network), use stage energy | E(delivery_relay, kWh) |
First-order, part 2, use stage GHG | C(delivery_relay, lifecycle, kgCO2e) |
First-order, part 3 (data centre), use stage energy | E(data centre, kWh) |
First-order, part 3, use stage GHG | C(data centre, lifecycle, kgCO2e) |
First-order, part 4 (marketing and operations support) | N(no_record) |
First-order, other life-cycle stages | N(embodied) |
Reference scenario | N(outside_records) |
Net second-order effect | N(outside_records) |
Higher-order effects | N(outside_records) |
Data quality | Q(operational, primary or modelled) |
Emission factors | F(operational, lifecycle) |
Initial guidance | T(higher-order effects are not supplied; the assessment gives initial guidance only (clause 11.5)) |
8.4 GHG Protocol Scope 2 Guidance
ghg-scope2. The inventory asks scope 2 emissions by the location-based and by the
market-based method, each labelled (7.1), from generation-only factors (4.2), with the
electricity consumed recommended beside them (7.2). The figures an export holds of an
operator’s own consumption are its hops’; a sink’s and a half’s are someone else’s, and are
in no field here. A field’s status is about the export’s own figures (§4 rule 3). Against the
guidance every figure is a part: a hop’s figure is its counter’s scope, not the site’s
metered electricity that scope 2’s activity data is.
| field | quantity |
|---|---|
Electricity consumption | E(delivery, MWh) |
Scope 2, location-based | C(delivery, generation, tCO2e) |
Scope 2, market-based | N(market_based) |
Location-based emission factors | F(delivery, generation) |
Contractual instruments | N(market_based) |
Base year | N(outside_records) |
8.5 GHG Protocol ICT Sector Guidance
ghg-ict. A service’s footprint per functional unit, its elements reported apart (1.8.8),
the use stage in kWh and kgCO2e with the factors stated (1.8.8), factors that include the
energy source’s life cycle (1.8.6), shared components allocated by use (1.8.4), and primary
and secondary data documented (4.5).
| field | quantity |
|---|---|
Data centre, use stage energy | E(data centre, kWh) |
Data centre, use stage GHG | C(data centre, lifecycle, kgCO2e) |
Network, use stage energy | E(delivery_relay, kWh) |
Network, use stage GHG | C(delivery_relay, lifecycle, kgCO2e) |
End-user devices, use stage energy | E(user premises, kWh) |
End-user devices, display (estimate) | E(device_display, kWh) |
End-user devices, use stage GHG | C(user premises, lifecycle, kgCO2e) |
Embodied emissions | N(embodied) |
Per functional unit: a viewing hour | I(delivery, viewing_us, 3.6×10⁹, kWh per viewing hour) |
Per functional unit: a gigabyte delivered | I(delivery, delivered_bytes, 10⁹, kWh per GB) |
Allocation | T(none: each figure is one hop's or one half's own over its span, allocated to no user) |
Primary and secondary data | Q(operational, primary or secondary) |
Electricity emission factors | F(operational, lifecycle) |
8.6 ISO/IEC 21031 (SCI)
iso-iec-21031. SCI = ((E × I) + M) per R: E the energy of the software boundary in kWh,
I a region-specific carbon intensity that excludes market-based measures, M the embodied
emissions of its hardware, R the functional unit; disclosed with the boundary and the
methodology (Procedure). WAI supplies E and, with a factor table, E × I; it supplies no
M, so it states no SCI score, and states the operational part per R. Version 1.0 of the
text asks marginal emission rates for I; version 1.1 also admits averages, which is what a
location-based factor table states.
| field | quantity |
|---|---|
E | E(operational, kWh) |
I | F(operational, generation) |
O = E × I | C(operational, generation, gCO2e) |
M | N(embodied) |
SCI | N(embodied) |
E per R, R = a viewing hour | I(delivery, viewing_us, 3.6×10⁹, kWh per viewing hour) |
E per R, R = a gigabyte delivered | I(delivery, delivered_bytes, 10⁹, kWh per GB) |
O per R, R = a viewing hour | CI(delivery, generation, viewing_us, 3.6×10⁹, gCO2e per viewing hour) |
O per R, R = a gigabyte delivered | CI(delivery, generation, delivered_bytes, 10⁹, gCO2e per GB) |
I as a marginal rate (version 1.0) | N(average_factor) |
Software boundary | T(the hops, sinks and split computations of the sources; a display is outside it; no embodied hardware) |
8.7 SCI for AI
sci-ai. A consumer score per functional unit of the service (an inference for a classical
model), over the operation stage; a provider score over training. WAI’s one computation per
split source is one inference over one tensor (task-fidelity §5.4). A claim states no
span, so it has no carbon.
| field | quantity |
|---|---|
Consumer E | E(computation, kWh) |
Consumer E per R, R = an inference | I(computation, computations, 1, kWh per inference) |
Consumer O | C(computation, generation, gCO2e) |
Consumer M | N(embodied) |
Consumer SCI | N(embodied) |
Provider SCI | N(no_record) |
Functional unit | T(an inference: one composed split computation, its head and its tail) |
8.8 DIMPACT
dimpact. The footprint of serving a digital media product over a period of at least one
calendar month, per component: data centre processes (its equation 1, from the owner’s
energy data), CDN (supplier energy data, its equations 7 and 8), the internet network (data
volume × an intensity, its equation 2), the home router and end-user devices (duration ×
power, its equation 13), location-based generation-only factors by default. WAI supplies its
hops’ energy as the owner’s and supplier’s data, the data volume, and a device’s measured
decode energy where the methodology models it; it supplies no network or home router energy,
and no intensity per byte stands in for one.
| field | quantity |
|---|---|
Data centre processes, energy | E(data centre, kWh) |
Data centre processes, GHG | C(data centre, generation, kgCO2e) |
CDN, energy (supplier data) | E(delivery_relay, kWh) |
CDN, GHG | C(delivery_relay, generation, kgCO2e) |
Internet network, energy | N(no_record) |
Data volume served | U(delivered_bytes, GB) |
Home router (CPE), energy | N(no_record) |
End-user devices, energy (measured) | E(user premises, kWh) |
End-user devices, display (estimate) | E(device_display, kWh) |
End-user devices, duration of content decoded | U(media_us, h) |
End-user devices, duration presented | U(presented_us, h) |
Standby | N(no_record) |
Embodied emissions | N(embodied) |
Assessment period | D |
Emission factors | F(operational, generation) |
8.9 Greening of Streaming
greening-of-streaming. No reporting format is published. Its public measurement work
measures power per component of a delivery chain (encoder, origin and packager, cache,
telco, home, end device) with an instrument at a stated sampling interval and resolution.
The form states WAI’s figures per those components.
| field | quantity |
|---|---|
Encoder | E(delivery_compositor, Wh) |
Origin/Packager | E(delivery_ingest, Wh) |
Cache | E(delivery_relay, Wh) |
Telco | N(no_record) |
Home | N(no_record) |
End-Device | E(device_decode, Wh) |
End-Device, display (estimate) | E(device_display, Wh) |
Measured or estimated | Q(operational, measured or estimated) |
8.10 AFNOR SPEC 2314
afnor-spec-2314. Its public summary states the indicators (climate change, final and
primary energy, water, resource depletion, ocean acidification, fine particles, ionising
radiation), the functional unit (the AI service to all its users over a year), the life
cycle as its boundary, and what a quantitative communication states. The form reads the AI
work WAI’s records name as such, the split computations. Not covered: the text itself.
| field | quantity |
|---|---|
Final energy consumption | E(computation, kWh) |
Climate change | C(computation, generation, kgCO2e) |
Primary energy consumption | N(no_record) |
Water | N(no_record) |
Depletion of natural resources | N(no_record) |
Ocean acidification | N(no_record) |
Fine particles | N(no_record) |
Ionising radiation | N(no_record) |
Database used for the impact | F(computation, generation) |
Location of computing and storage | R(computation) |
Scope of the life-cycle assessment | T(the use stage of the split computations; no other life-cycle stage) |
Frugality | N(no_claim) |
8.11 Blauer Engel DE-UZ 215
de-uz-215. Its criteria measure a software product’s energy on a defined test system as
net values above the system’s base load for a standard usage scenario (3.1.1.4), with a
meter whose tolerance is stated (3.1.1.2), at least ten runs within a relative standard
deviation of 5 % (Annex A 1.1). WAI supplies a sink’s net decode energy (an idle bracket
taken off, energy-measurement §3) and a hop’s own, with the declared uncertainty, and none of
the scenario statistics.
| field | quantity |
|---|---|
Energiebedarf (Wh), netto: client decode | E(device_decode, Wh) |
Energiebedarf (Wh): server | E(delivery, Wh) |
Messmethode | Q(operational, class label) |
Toleranz (%) | P(operational) |
Messdurchläufe und relative Standardabweichung | N(no_record) |
Grundauslastung und Leerlauf | N(no_record) |
Übertragene Datenmenge | N(no_record) |
8.12 UNE 0086:2025
une-0086. Its public scope names energy consumption, carbon footprint, water consumption
and performance of an AI system across its life cycle, on premises and in the cloud. Not
covered: the text.
| field | quantity |
|---|---|
Energy consumption | E(computation, kWh) |
Carbon footprint | C(computation, generation, kgCO2e) |
Water consumption | N(no_record) |
Performance | N(no_record) |
8.13 CEN/CLC/TR 18145:2025
cen-clc-tr-18145. Its public scope names an AI system’s operational energy, its other
resources (water) and its carbon footprint. Not covered: the text.
| field | quantity |
|---|---|
Operational AI energy consumption | E(computation, kWh) |
AI carbon footprint | C(computation, generation, kgCO2e) |
Water | N(no_record) |
Avoided emissions | N(no_claim) |
9. Verification
A verifier is given the sources, the factor table or none, and the export. It stops at the first refusal, which it reports with its reason and its place, a list:
- The sources, in order, at
["sources", i],ithe source’s place in the list from 0: each reads as its kind (§7.1), elsesource_malformed; each verifies under its extension, elsesource_refused, with that extension’s reason beside it. - The records, at
["sources", i],ithe later source: no record is read twice (§7.2), elserecord_duplicate. - The table, at
["factors"]: it meets §6.2, elsefactors_invalid. - The export, at
["export"]: it is an object of exactly §7’s members,wai_energy_exportthe integer 1,signerandsighexadecimal of 32 and 64 bytes,factorsandperiodeach an object ornull, the other members arrays, and every number in it an integer of §2, elseexport_malformed; its signature verifies (bad_key,bad_signature). - The recomputation: the verifier computes the export’s body again from the sources and
the table, with the stated
signer. Where the two are equal the export is accepted. Otherwise it goes through the members in the order below and stops at the first that differs. For a member that is a list of rows, the place is the member andi, the first position at which the stated list and the recomputed one differ or only one has a row; a stated row is matched to the recomputed row with the same members named.sources, thenfactors: a source or the table that the export does not name as given,not_recomputable, at["sources"]or["factors"].figures, at["figures", i]. Where both have a line ati, the first of: the recomputed line is the unmetered marker and the stated one has aclassor auj,unmetered_as_zero; at a scope,generationthenlifecycle, the stated line states carbon (aug) and the recomputed one states none or names another factor:carbon_unsourcedwhere no table is given or the statedfactoris no place in the table’sfactors, andfactor_mismatchotherwise, the factor being one of another region, scope or period than the figure’s site, the scope and the figure’s span. Otherwisenot_recomputable.energy, at["energy", i]. The stated row ati, matched bycomponentandclass, is the first of: one whoseujis the matched row’s together with those of one or more of the recomputed rows of its component of other classes,classes_summed; one whosecitesname the record of an unmetered figure of its component,unmetered_as_zero; one statedwholewhose matched row ispartial,partial_as_whole. Otherwise, and where the stated list has no row ati,not_recomputable.unmetered, at["unmetered", i]: where an unmetered figure’s record is cited by no stated row of its component,unmetered_as_zero; otherwisenot_recomputable.carbon, at["carbon", i]. The stated row ati, matched bycomponent,classandscope, is the first of: one stating augwhere no table is given and no matched row states one,carbon_unsourced; one statedwholewhose matched row ispartial,partial_as_whole. Otherwisenot_recomputable.units, at["units", i]: where the recomputed row atiisviewing_usordelivered_bytesand the stated row’svalueis not the signed sum of §5.1 or §5.2,denominator_mismatch; otherwisenot_recomputable. Thenderived, at["derived", i]. The stated row ati, matched byfigureandclass, is the first of: one whoseoveris not the matched row’s,denominator_mismatch; one whoseujis the matched row’s together with those of one or more of the recomputed rows of itsfigureof other classes,classes_summed; one statedwholewhose matched row ispartial,partial_as_whole. Otherwisenot_recomputable.forms, at["forms", m],mthe first form that differs: where itsmethod,revision,not_coveredand number of fields are the recomputed form’s, at["forms", m, "fields", f],fits first field that differs: one statedsuppliedthat ispartial,partial_as_whole; otherwisenot_recomputable.period, at["period"], and any other difference, at["export"]:not_recomputable.
An accepted export’s outcome is its identity and its CSV (§7.4).
10. Reasons
| reason | raised at |
|---|---|
source_malformed | §9 step 1 |
source_refused | §9 step 1 |
record_duplicate | §7.2, §9 step 2 |
factors_invalid | §6.2, §9 step 3 |
export_malformed | §9 step 4 |
not_recomputable | §9 step 5 |
unmetered_as_zero | §9 step 5 |
carbon_unsourced | §9 step 5 |
factor_mismatch | §9 step 5 |
classes_summed | §9 step 5 |
partial_as_whole | §9 step 5 |
denominator_mismatch | §9 step 5 |
A verifier also raises bad_key and bad_signature for the export (SPEC §7
Signatures), and reports a source’s own reason beside source_refused.
11. Conformance
live-conformance/energy-methods/ holds the corpus,
one file, vectors.json, written by wai_energy_methods_vectors gen. Its sources are
records of the live-metering, sink-energy and machine-coding corpora, read from their
committed files; its factor tables and exports are signed from fixed seeds, and its factors
are made up for the corpus. Each vector is a list of sources, a factor table or none, an
export, and the outcome §9 gives them:
- Accepted: a delivery whose hops are all one class, with carbon at both scopes; a delivery of three classes; a receipt of version 2 whose delivered bytes are its own unit; a delivery with an unmetered hop; the same records with no factor table; a table that leaves every figure without carbon, each for its own reason of §6.3; one export over rooms, sinks of three classes and split computations whole and partial; one with no room; and one with no source at all.
- Refused: each reason of §10 at least once, and both signature codes. The faults of §9 step 5 are each planted in an otherwise correct export that is then signed again, so that its signature is never what refuses it: a figure of another class summed into a row and into a per-viewing-hour figure; an unmetered figure written as zero, counted in a row, and left out of the unmetered rows; carbon with no factor table, in a line and in a row, and carbon naming no factor of the table; a factor of another region, of another period and of another scope; a viewing time that counts layer class 8, a per-viewing-hour figure over the session’s length, and bytes delivered that count bytes received; a figure that is not its record’s, a form field no row gives, another source named, and another period; and a partial row, carbon row, derived figure and form field each stated whole. Before the export is read: a source of another form, a source of each kind that does not verify, a record two sources read, and tables with a factor of zero, a factor with no source, a market-based basis, overlapping periods and sites, and a factor changed after signing.
wai_energy_methods_vectors verify and the test tests/energy_methods.rs check that the file
regenerates byte for byte, that wai-rs gives every vector its outcome, that every reason
of §10 refuses a vector, that §10 lists exactly the reference’s codes, that §8’s tables are
the forms the reference writes, and that a stated outcome changed to another is noticed.
live-conformance/energy_methods_verify.py is the second implementation, written from this
text: it shares no code with wai-rs, verifies each source with that corpus’s own second
implementation (live_metering_verify.py, sink_energy_verify.py, claim_verify.py and
machine_coding_verify.py), verifies signatures with WAI’s strict rule written from
RFC 8032 (claim-conformance/_ed25519.py), reads the forms and their fields from §8’s tables
as this text writes them, recomputes every export itself, gives every vector the same outcome
and CSV, requires every mutated copy of the corpus to fail, and runs once with each of its
checks dropped, each such run failing on the corpus.
12. Security and privacy considerations
- An export restates what signed records state. Its signature makes the export attributable to its exporter; the figures remain their signers’ statements, and their classes say how they were obtained (energy-measurement §5). A verifier recomputes every row from the records, so an exporter cannot state a figure no record states.
- A factor table states where an operator’s hops ran, by region and period. An operator that gives its table to a reader discloses that.
- An export names no person: a sink’s session is random per viewing session (sink-energy §10), and the units are sums over sessions. A room’s units are its receipt’s, which a deployment that publishes a receipt already publishes.