S3-CAT
Scope 3 Category Aggregation
1. Identity
Depends on module:
-
Purpose: Produces category-level Scope 3 totals (Cat1–Cat15) from granular inputs, enforcing Scope 3 category semantics, completeness metadata, and category normalization rules aligned with GHG Protocol Scope 3 Standard and ESRS E1.
-
Typical usage:
- Reporting Scope 3 by category (Cat1…Cat15)
- Rolling up subcategory line items (e.g., Cat6 Business Travel) into Cat6
- Feeding Scope 3 totals into
MEID_CALC_GHG_AGGR - Computing category shares (often via
MEID_CALC_SHARE)
Versioning policy
- MEID is stable.
- Category logic and mappings (e.g., subcategory→category) are governed via ZAR and referenced datasets.
2. Contract References (ZAR)
2.1. Input Schema
- ZAR Address:
schema.compute.ghg.scope3.cat.inputs.v1_0_0
Required conceptual fields
items: list of Scope 3 emission items (granular records)item_value_unit: defaulttCO2e(or each item specifies its unit)category_map_ref: optional reference to a canonical mapping set (subcategory → Cat1–Cat15)group_by:CATEGORY|CATEGORY+SUBCATEGORY(defaultCATEGORY)alignment:BY_YEAR|BY_INDEX(defaultBY_YEAR)
Each item conceptually includes:
category(optional if subcategory + mapping is provided)subcategory(optional; canonical key strongly recommended)period(year or period key)value- optional
source_id/activity_idfor traceability
2.2. Options Schema
- ZAR Address:
schema.compute.ghg.scope3.cat.options.v1_0_0
Common options:
unknown_category_policy:ERROR|DROP|ASSIGN_OTHERother_bucket_name: default "cat_other"duplicate_item_policy:ALLOW|DEDUPE_BY_ID|ERRORnegative_values_policy:ERROR|ALLOW_WITH_FLAGexpected_categories: optional list (for completeness scoring)rounding: optional digits
2.3. Output Schema
- ZAR Address:
schema.compute.ghg.scope3.cat.output.v1_0_0
Outputs include:
scope3_by_category: map catX -> series- optional
scope3_by_subcategory(if grouped) scope3_total(sum across included categories)metadata(completeness, unknowns, dedupe actions, mapping version)
3. Accepted Input Shapes
A. Item list (preferred)
{
"items": [
{"subcategory": "cat6.business_travel.air", "period": 2025, "value": 120},
{"subcategory": "cat6.business_travel.rail", "period": 2025, "value": 30},
{"subcategory": "cat1.purchased_goods", "period": 2025, "value": 800}
],
"category_map_ref": "MAP.SCOPE3.SUBCAT_TO_CAT.v1",
"group_by": "CATEGORY"
}
B. Items already category-tagged
{
"items": [
{"category": "cat6", "period": 2025, "value": 150},
{"category": "cat1", "period": 2025, "value": 800}
]
}
C. Time-series per category (legacy-friendly)
{
"items": [
{"category": "cat6", "values": [[2025, 150], [2026, 140]]},
{"category": "cat1", "values": [[2025, 800], [2026, 780]]}
],
"alignment": "BY_YEAR"
}
All inputs MUST be normalized internally to:
Map<period, Map<category, value>> (+ optional subcategory dimension).
4. Category Normalization Rules (Normative)
4.1. Canonical category identifiers
Accepted canonical forms (schema-enforced):
cat1 … cat15(case-insensitive input; output MUST use lowercasecatX)- Output keys MUST be normalized to
cat1..cat15.
4.2. Subcategory mapping
If category is missing but subcategory is present:
- engine MUST resolve
subcategory→categoryusing:- explicit mapping in the item (if present), else
category_map_ref, else- error (depending on
unknown_category_policy)
4.3. Unknown categories
If an item cannot be mapped to a valid cat1..cat15:
ERROR: fail the computationDROP: omit item and record in metadataASSIGN_OTHER: place intoother_bucket_name(discouraged for regulated reporting; allowed for internal use)
5. Compute Semantics (Normative)
For each period t and category c:
S3_CAT(c,t) = Σ value(item_i) for all items mapped to category c in period t
And the total:
S3_TOTAL(t) = Σ S3_CAT(c,t) for all included categories c
Unit handling
- All items MUST be converted to
tCO2eunless schema explicitly allows mixed units. - Output values MUST be in
tCO2e.
Duplicate handling
If duplicate_item_policy = DEDUPE_BY_ID:
- items sharing the same
source_id/activity_idand period are counted once - dedupe actions MUST be recorded in metadata
6. Completeness & Coverage Metadata (Normative)
This engine MUST output completeness indicators suitable for ESRS-style narratives and internal QA:
categories_present: set of categories observedexpected_categories: from options or defaults (Cat1–Cat15)coverage_ratio:
coverage_ratio = |categories_present ∩ expected_categories| / |expected_categories|
unknown_items_count(and list of unknown keys when allowed)negative_items_count(if allowed)
Important:
coverage_ratiois category presence, not magnitude completeness. It is a structural completeness signal.
7. Alignment Rules
BY_YEAR
itemsMUST have aperiodkeyoutputis keyed by year/period
BY_INDEX
- only permitted for already-shaped time-series items
- discouraged for category rollups because items are naturally period-keyed
8. Validation & Error Model
Invariants
- item values must be finite numbers
- negative values default to error unless
negative_values_policyallows with flag - category mapping must resolve deterministically
Error codes (suggested)
SCOPE3_CAT_MAPPING_NOT_FOUNDSCOPE3_CAT_INVALID_CATEGORY_CODESCOPE3_CAT_UNKNOWN_CATEGORY_POLICY_ERRORSCOPE3_CAT_DUPLICATE_ITEM_ERRORSCOPE3_CAT_NON_FINITE_VALUE
Errors MUST include:
- engine
cmi_short_code - offending item reference (index +
source_idif available) - period and category/subcategory
9. Dependencies
MEID_CALC_GHG_SCOPE3_CAT depends on:
- schema resolver (ZAR)
- canonical Scope 3 category reference list
- optional mapping dataset (
category_map_ref) for subcategory → category - unit conversion utilities
These are declared in ZAR via dependencies (CMIs and/or dataset refs).
10. Federation & Audit Requirements
To reproduce category rollups externally, the export MUST include:
- Engine identity (
cmiorzar_code) - Engine build proof (
execution_ref+build_hash) - Input/options/output schemas used
- Input item list (or aggregated category series)
- Mapping reference artifact (if used), including its hash/version:
category_map_refresolution + proof
- Any dedupe policy applied and evidence fields used (
source_id)
Provenance chain MUST show:
… → MEID_CALC_GHG_SCOPE3_CAT → …
with the engine cmi_short_code in USO tails.
11. Performance Notes
- Complexity: for mapping + accumulation
- Memory: + optional subcategory dimension
- Suitable for batch pipelines; can be streamed if items are sorted by period
12. Methods Served (v1)
- GHG.scope3.cat.abs (category totals)
- GHG.scope3.cat.share (category shares, typically via MEID_CALC_SHARE after totals)
- GHG.scope3.abs (when summed to a single Scope 3 value, often consumed by MEID_CALC_GHG_AGGR)