S3-PO
Scope 3 Post Office
1. Identity
Depends on module:
| Property | Value |
|---|---|
| Role in the family | Engine 1 of 17 (S3-ARCH 4.1) — the only place a Scope 3 category is assigned |
| MICE type | META — attaches taxonomic meaning, never alters a quantitative value |
| Pipeline position | Context Enrichment stage of the canonical TrustGate pipeline (S3-ARCH 3.1) |
| Input | comp.S3-PO.INPUT.ENVELOPE.v1_0 — schema schemas/mice/scope3/s3po-envelope.v1.schema.json |
| Output | comp.S3-PO.OUTPUT.CATEGORY_ASSIGNMENT.v1_0 — artifact ARTIF-ADENGINE-SCOPE3-CATEGORY-ASSIGNMENT, identifier S3AID, schema schemas/mice/scope3/s3po-category-assignment.v1.schema.json |
| Event | comp.S3-PO.EVENT.ASSIGNMENT_DELTA.v1_0 — schema schemas/mice/scope3/s3po-assignment-delta.v1.schema.json |
| Classification ruleset | ruleset.classification.ghg.global.scope3-category-assignment.standard.CRITICAL.1_1_0 |
| Routing ruleset | ZSSR.Router.RuleSet.S3PO.2026_10_13 |
| Governed configuration | config/system/scope3/ — account classes, chart mappings, category maps, parameter set |
| Reference implementation | scripts/scope3/s3po_reference.py, tests in scripts/scope3/tests/ |
This document is a child of the Scope 3 Engine Architecture (S3-ARCH). Where the two disagree, this document is in defect (S3-ARCH section 1).
2. Purpose
The Post Office answers one question for every value-chain signal ZAYAZ receives: which Scope 3 category does this belong to — and if none, why not?
It does this once, in one engine, with evidence, so that every consumer — the fifteen category controllers, ledger tagging at ingestion, supplier onboarding, the ESGX/PCAF profile, the ESRS E1-6 category breakdown and Watchtower — reads the same governed answer.
The Post Office:
- classifies, it never computes an emission value;
- stamps, it never routes — routing is ZSSR's (S3-ARCH D4);
- holds what it cannot decide, it never guesses (S3-ARCH D5);
- decides by rule, and lets AI propose but never decide (S3-ARCH D6);
- is chart-agnostic: it never reads an account number; charts of accounts are mapping data (section 4).
2.1. Outcomes
Every envelope receives exactly one outcome:
| Outcome | Meaning | Next engine (section 11) |
|---|---|---|
ASSIGNED | one category cat1 … cat15, with direction and, for cat 3, the sub-activity | the category controller S3-C01 … S3-C15 |
SPLIT | the envelope spans categories; child envelopes are emitted, each assigned | each child re-enters the Post Office |
REROUTE_SCOPE1 | the signal belongs to Scope 1 | S1-CON |
REROUTE_SCOPE2 | the signal belongs to Scope 2 | S2-CON |
NOT_APPLICABLE | no Scope 3 relevance, with a reason code | terminal; recorded as a ledger note |
HOLD | not decidable at the required confidence, with a reason code and, where one exists, a suggested outcome | TG-QUARANTINE-MANAGER |
2.2. What the Post Office does not do
- compute quantities, select calculation methods or score data quality — controllers do (S3-ARCH 6);
- screen categories for relevance or justify exclusions — controllers and
S3-SUMdo; - resolve double counting across categories —
S3-SUMdoes; - validate physical activity data — ACF semantic resolution does (
ACF-GOVERNED-CONNECTOR-SCHEMA-V1sections 17–18). The Post Office consumes envelopes whose activity semantics ACF has already resolved, and never upgrades an ACF data-quality level.
3. The Envelope
All input arrives as one envelope with an adapter-typed subject. The common part identifies the reporting scope and the source; the subject carries the facts the ruleset discriminates on.
3.1. Common fields
| Field | Required | Source | Purpose |
|---|---|---|---|
envelope_id, envelope_hash | yes | producer | identity and idempotency; the hash covers every field except itself |
adapter | yes | producer | one of the six adapters (3.2) |
reporting_context.eco_id, ebu_id, ebp_id | eco_id yes | ACF identity resolution (ECO, EBU, EBP) | reporting entity and scope |
reporting_context.period | yes | producer | reporting period |
reporting_context.consolidation_approach | yes | client configuration | operational_control, financial_control or equity_share; read by controllers for the Scope 1/2 boundary |
source.* | source_record_id, acf_dq_level | ACF | connector, interface, record, revision, mapping version, ACF-DQ1…DQ5 level, evidence references |
amount, quantity, description_text | no | ACF canonical fields | used by rules, split rules and the AI tier |
upstream_category | no | an upstream engine or an accepted supplier declaration | feeds the EXPLICIT tier (5.2) |
human_override | no | quarantine review | feeds the HUMAN_OVERRIDE tier (5.2) |
parent_envelope_id | no | Post Office | set on split children and override re-entries |
The Post Office never mutates an envelope. A changed source record arrives as a new envelope with a new hash (restatement cause ENVELOPE_REVISION).
3.2. Adapters
One envelope contract, six typed subjects. The classification logic is shared; adapters only normalise their source into the subject.
| Adapter | Source | Subject carries | Typical outcomes |
|---|---|---|---|
transaction | general-ledger and AP lines through ACF connectors (TAC, AP-CONN, INV-GHG, SIE, Xledger, Tripletex, Fortnox, …) | account_code, resolved account_class and its resolution, entry_side, document_type, contra_account_class, capitalised, payer, counterparty_in_boundary, supplier (E-C-O, NACE code and version, role), invoice lines, ownership, lease type and control facts | cat 1, 2, 4, 5, 6, 7, 8, 13, 14; reroutes; not applicable |
supplier | supplier onboarding (SUPP-ONBOARD) and the UOM relationship graph | supplier identity, NACE, value-chain role, UOM relationships | default category of a supplier relationship, used for engagement and corroboration |
activity | travel bookings, shipments, waste manifests, fleet and commuting data | activity_type, mode, payer, shipment direction, traveller role and purpose, ownership, lease type | cat 4, 5, 6, 7, 9, 12; reroutes |
product | sold-product and BOM records | sold, intermediate, energy-using, fuel, GHG-containing, downstream processing, end-of-life routes, distribution payer | cat 9, 10, 11, 12 (fan-out) |
asset | lease, franchise and asset registers | lease direction, lease type, ownership, operational control, franchise role | cat 8, 13, 14, or not applicable, by lease type and consolidation approach (6.6) |
investment | portfolio holdings | PCAF asset class, investee, outstanding amount, whether the investee is consolidated | cat 15; not applicable for consolidated investees |
Ownership, lease direction and operational control are read from the UOM relationship graph (OWNS, LEASES / LEASED_BY, OPERATES) at the envelope's effective date; lease type (operating or finance) comes from the lease register under the client's accounting framework. Supplier NACE codes are carried numerically, without section letter, with their revision (nace_version 2 or 2.1), because NACE Rev. 2.1 moves section letters (section 7). UOM has no franchise relationship type; until one is registered, franchise role comes from the asset register (section 17).
3.3. Schema
The normative contract is schemas/mice/scope3/s3po-envelope.v1.schema.json (JSON Schema 2020-12). An envelope that fails the schema is rejected with S3PO_ENVELOPE_SCHEMA_INVALID (section 14) and never classified.
4. Chart-Agnostic Account Classification
4.1. Principle
A chart of accounts is a client's private vocabulary. ACF already states that an account is "a source signal rather than an ESG taxonomy" and leaves an account classification step to the engines. The Post Office implements that step through a governed, chart-independent vocabulary:
client account code
│ client chart mapping (extends a seed chart: NS4102, BAS, …)
▼
Scope 3 account class (config/system/scope3/account-classes.json)
│ classification ruleset + discriminators
▼
outcome
The ruleset tests account classes only, never account numbers. Supporting a new chart, a new country or one client's peculiar postings is a data change in config/system/scope3/chart-mappings/, never an engine or ruleset change.
4.2. Account classes
config/system/scope3/account-classes.json defines 54 classes. Each class declares:
| Field | Meaning |
|---|---|
code | stable lower-snake identifier, immutable once registered |
statement, nature | income statement or balance sheet; expense, capex, revenue, allowance, allocation, levy, financial, balance or elimination |
default_outcome | the outcome the class implies before discriminators |
candidate_categories | categories the class can lead to |
discriminators | envelope facts the ruleset uses to refine the outcome (from a closed vocabulary) |
note | the GHG Protocol reasoning behind the class |
The vocabulary encodes the boundary decisions that are otherwise made inconsistently in practice, among them:
- capital versus expensed:
capex_*classes are cat 2 on additions only;depreciation_amortisationis not applicable, because capital goods are reported in full in the year of acquisition; transfers between capital accounts (construction in progress to the finished asset) are internal and not counted again; - freight:
freight_purchasedis cat 4 whenever the reporting company pays, inbound or outbound; cat 9 never arises from the company's own ledger;freight_and_customs_combinedseparates customs duties, which are not purchases, before cat 4 is assigned; - energy:
energy_electricityandenergy_heat_steam_coolingreroute to Scope 2,fuel_stationaryto Scope 1; cat 3 is derived later from the validated Scope 1/2 data (S3C-006), never from these envelopes; - allowances: mileage allowances for private cars are cat 6; per diem allowances are not purchases and are not applicable;
- combined utility charges: water with wastewater, and municipal waste with water and cleaning, are split by invoice line;
- ambiguous groups hold by class, not by confidence:
other_unspecifiedandvehicle_costs_unspecifieddefault toHOLD, so a verified mapping cannot turn an ambiguous account into an automatic decision; - investments and revenue: classified through the
investmentandproductadapters, never from ledger postings.
4.3. Chart mappings
A chart mapping (config/system/scope3/schemas/chart-mapping.schema.v1.json) maps account codes to classes with exact, range or prefix matches, each with a prior confidence. Two kinds exist:
| Kind | scope | Example | Maintained by |
|---|---|---|---|
| Seed chart | seed | NS4102 (Norway), BAS (Sweden) | ZAYAZ, governed change |
| Client chart | client | one ECO's chart, extends a seed | the client's accountant, governed change |
Before classification, the reference recomputes envelope_hash over every envelope field except the hash itself and rejects mismatches. Rule discriminator evidence includes values referenced by the adapter's governed rule predicates, including nested supplier fields.
A supplied non-null transaction account_class requires a complete, non-null account_class_resolution; missing evidence is rejected before classification. The resolution records the effective client chart_id and chart_version, plus seed_chart_id and seed_chart_version for an inherited match (null for an own entry). effective_chart_hash pins the complete client-first inheritance chain, including verification records, as SHA-256 over sorted-key compact UTF-8 JSON without ASCII escaping. This binds replay to the attestation actually used, even when the matching seed entry is unchanged.
Resolution precedence (normative): client exact, client range, client longest prefix, then the same order in the seed the client chart extends, then unmapped. An unmapped account yields account_class: null; the envelope then proceeds to the MAP tier and is held with HOLD-UNMAPPED-ACCOUNT if nothing decides it. scripts/scope3/resolve_account_class.py is the executable statement of this rule. Range bounds are inclusive, equal-length strings, including alphanumeric account codes. When several ranges match, select the unique range contained in every other matching range. Reject ambiguous overlaps or duplicate equally specific ranges rather than selecting by file order or numerical width. This applies to numeric ranges as well.
The seeds cover the stable structure of each standard: account groups and the accounts that do not change between editions. Two findings shaped them:
- NS 4102 posts inbound freight inside cost of goods (4060, 4260 Frakt, toll og spedisjon); these map to
freight_purchased, notpurchased_goods, or inbound freight would be misreported as cat 1. - BAS reuses account numbers between editions (5618 is a mileage cost in BAS 2018 and congestion tax in BAS 2023). The BAS seed therefore contains only edition-stable accounts; edition-specific accounts belong in client mappings.
- Both charts hide purchases inside non-purchase groups and non-purchases inside purchase groups: training and occupational health inside BAS personnel costs (76xx), insurance and gifts inside NS 4102 payroll (59xx), property tax inside BAS property costs (5191), accumulated depreciation inside fixed-asset groups (BAS xx18/xx19), customs duties inside freight accounts. Each is mapped explicitly; a group-level prefix alone would misclassify them.
4.4. Verification lifecycle
A seed is a starting point, not an attestation about a client. Every client mapping carries a verification status:
| Status | Resolution confidence | Effect |
|---|---|---|
unverified_seed | entry confidence, capped by s3po.unverified_mapping_confidence_cap | below every auto-accept threshold: rule decisions are held with HOLD-UNVERIFIED-MAPPING unless an independent signal (supplier NACE in the MAP tier) agrees |
verified | 1.0 | the rule's own confidence governs |
Verification is performed once per client by the client's accountant, who reviews the effective mapping for the accounts the client actually uses (own entries and inherited seed entries) and attests it. Verification attests the whole effective mapping, so inherited seed entries are verified with it. Entry confidence orders that review (lowest first); after verification it no longer affects decisions. Re-verification is required when the client chart or its seed changes version.
A verified record requires a nonempty list of distinct, nonblank verified_by
identities and a valid RFC 3339 verified_at timestamp. Missing or malformed
attestation fields reject the chart at configuration loading and direct resolution;
they never grant full confidence. The same checks apply throughout an inherited chart
chain. Unverified seeds retain their confidence cap. The reference checks require
requirements-kismet.txt, including its explicit timestamp-validation dependency.
These fields record the accountant's attestation; the trusted configuration publisher remains responsible for authenticating the accountant and authorizing the governed change. Filling fields in an untrusted envelope cannot create that authority.
This is the governance gate that lets an accounting firm put its name to a client's Scope 3 inventory: nothing is auto-classified on a mapping no accountant has confirmed.
4.5. Chart detection
The chart a client uses is a client configuration fact, confirmed at onboarding. Detection hints in each seed propose it: the SIE #KPTYP chart-type value, the ACF connector in use and the client's country. A hint never selects a chart on its own.
5. Decision Ladder (Normative)
5.1. Tiers and precedence
| Order | Tier | Fires when | Confidence | Decides |
|---|---|---|---|---|
| 1 | HUMAN_OVERRIDE | the envelope carries human_override (a quarantine resolution re-entering) | 1.0 | yes |
| 2 | EXPLICIT | the envelope carries upstream_category from a registered engine or an accepted supplier declaration | 1.0 | yes, unless a consistency check fails (5.5) |
| 3 | RULE | a classification rule matches (section 6) | rule confidence, combined per 5.3 | at or above the threshold |
| 4 | MAP | a category map key matches (section 7) | entry confidence, capped by s3po.map_confidence_ceiling | at or above the threshold; corroborates or contradicts a rule candidate (5.4) |
| 5 | AI_PROPOSED | no candidate exists and the governed AI call returns a proposal (section 8) | capped by s3po.ai_confidence_cap | never — always HOLD |
| — | NONE | no tier produced a candidate | 0 | held with a reason code (HOLD-UNMAPPED-ACCOUNT or HOLD-NO-DECISION); NONE is valid only with HOLD |
Override precedes explicit because an override is a human decision about this very envelope. Explicit precedes rule because an upstream assertion carries its own evidence (for example a supplier's verified declaration or a TAC tag).
5.2. Threshold
The auto-accept threshold in force is resolved per client and per adapter through Policy Resolution from the administered set, and is never below s3po.auto_accept_threshold_min. Without a client value, s3po.auto_accept_threshold_default applies. The threshold in force is recorded on every assignment (threshold_in_force).
5.3. Confidence of a rule decision
rule decision confidence =
min(rule.confidence, account_class_resolution.confidence) if the rule tests subject.account_class
rule.confidence otherwise
So a correct rule on an unverified mapping cannot auto-accept: the mapping, not the rule, is the weak link, and the hold reason says so (HOLD-UNVERIFIED-MAPPING).
5.4. Corroboration and conflict between RULE and MAP
When the rule tier yields a candidate below the threshold, the MAP tier is consulted:
| MAP result | Effect |
|---|---|
| same outcome and category as the rule candidate | confidence becomes the higher of the two; the tier is recorded as MAP if the map was the stronger signal |
| different outcome or category, at or above the threshold | HOLD with HOLD-CONFLICTING-SIGNALS; both candidates are attached as the suggestion |
| different, below the threshold | ignored; the rule candidate stands |
| no match | the rule candidate stands |
Two independent signals that agree — the account says freight, the supplier is a road haulier — are stronger than either alone. Two that disagree are a finding for a human, never a vote.
The MAP tier is consulted on its own only when the account class is of low specificity (other_unspecified, vehicle_costs_unspecified, purchased_services_other, energy_purchased_unspecified), when the account is unmapped, or for the supplier adapter.
5.5. Stops and consistency checks
- A rule whose outcome is
HOLDrecords a conflict (for example a capital account posted as expensed, or stationary fuel for an installation the company does not control). It stops the ladder: neither the MAP nor the AI tier may override conflicting signals. EXPLICITconsistency: an explicitcat9on atransactionenvelope is a conflict, because the company's own ledger cannot contain distribution it did not pay for. Further consistency checks are added to the ruleset, never to engine code.
5.6. Hold reasons
| Reason code | Cause | Suggested outcome |
|---|---|---|
HOLD-UNVERIFIED-MAPPING | rule candidate capped by an unverified chart mapping | the rule candidate |
HOLD-BELOW-THRESHOLD | candidate exists but is below the threshold | the candidate |
HOLD-CONFLICTING-SIGNALS | a conflict rule fired, or RULE and MAP disagree | both candidates where applicable |
HOLD-SPLIT-NO-LINES | combined charge without invoice lines | none |
HOLD-SPLIT-INCOMPLETE | invoice lines classified cover less than s3po.split_min_line_coverage of the amount | none |
HOLD-AI-PROPOSAL | only an AI proposal exists | the AI proposal |
HOLD-UNMAPPED-ACCOUNT | the account has no mapping and nothing else decided | none |
HOLD-NO-DECISION | no rule, map or proposal applies | none |
A suggested outcome lets a reviewer confirm with one action — and confirm in bulk, for example every held envelope on one account for one client (section 11.3).
5.7. Not-applicable reasons
| Reason code | Cause |
|---|---|
NA-ACCOUNT-CLASS | the account class has no Scope 3 relevance (payroll, depreciation, taxes, financial items, balance movements, per diem, customs duties, revenue, ledger postings on investments) |
NA-INTRA-GROUP | the counterparty or investee is inside the reporting boundary |
NA-ASSET-DISPOSAL | credit posting on a capital account that is not a supplier credit note |
NA-INTERNAL-TRANSFER | transfer between capital accounts (counted when purchased) |
NA-PAID-BY-SUPPLIER | inbound transport paid by the supplier (embedded in cat 1) |
NA-IN-SCOPE12 | the asset is in the reporting company's Scope 1/2 under its lease type and consolidation approach (6.6) |
NA-FRANCHISEE-OWN-OPERATIONS | the reporting company is the franchisee |
6. Classification Ruleset
6.1. Identity
| Property | Value |
|---|---|
| File (draft) | code/rulesets/draft/scope3/s3po-scope3-category-classification.ruleset.yaml |
| Schema | schemas/zar/ruleset.v1.schema.json (validated) |
| CRID | ruleset.classification.ghg.global.scope3-category-assignment.standard.CRITICAL.1_1_0 |
| ZRR | rule type classification, enforcement hard, fallback manual_escalation, audit required, executed by MEID_GHG_CLASSIFY_SCOPE3 |
| Status | draft; held outside code/rulesets/prod/, which CI signs and publishes |
6.2. Grammar (rules.grammar_version: 1.0)
Each rule has an id, a unique priority, an adapter, a when block of predicates on envelope paths, a then decision and a confidence.
| Predicate | Matches when |
|---|---|
eq | the value equals the operand; null matches null or absent |
in | the value is one of the operands; null in the list matches null or absent |
present | true: present, non-null and non-empty; false: absent, null or empty |
any_prefix | any element of a list value starts with any operand (used for NACE) |
Evaluation: rules for the envelope's adapter in descending priority; the first match decides (first_match). The product adapter collects every match (collect_all) and fans out (6.5). Credit entries on expense classes are credit notes and take the class outcome with a negative amount; entry_side is tested only on capital classes.
6.3. Rule families
| Family | Rules | Decides |
|---|---|---|
| Boundary | R-TX-INTRA-GROUP | intra-group postings are not applicable |
| Capital goods | R-TX-CAPEX-CONFLICT, R-TX-CAPEX-INTERNAL-TRANSFER, R-TX-CAPEX-CREDIT-NOTE, R-TX-CAPEX-DISPOSAL, R-TX-CAPEX, R-TX-SMALL-EQUIP-CAPITALISED | cat 2 on additions and supplier credit notes; internal transfers and disposals not applicable; conflicts held |
| Exclusions | R-TX-NOT-APPLICABLE-CLASS | not-applicable classes (5.7) |
| Freight | R-TX-FREIGHT-PAYER-CONFLICT, R-TX-FREIGHT-FUEL-SUPPLIER, R-TX-SPLIT-FREIGHT-CUSTOMS, R-TX-FREIGHT-CUSTOMS-NO-LINES, R-TX-FREIGHT | cat 4 when the company pays; customs duties excluded by line; fuel suppliers on freight accounts held |
| Energy | R-TX-ENERGY-LEASED-OPERATING-FINCTRL, R-TX-ENERGY-FINCTRL-OWNERSHIP-UNKNOWN, R-TX-ENERGY-SCOPE2, R-TX-ENERGY-NACE-SCOPE2, R-TX-ENERGY-NACE-SCOPE1 | Scope 2, or cat 8 for operating-leased assets under financial control or equity share (6.6); unspecified energy resolved by supplier NACE |
| Fuel | R-TX-FUEL-STATIONARY*, R-TX-FUEL-VEH-* | by ownership, lease type and approach (6.6): Scope 1, cat 8, cat 6 (rental, private business), cat 7 (private commuting); unknown ownership or lease type proposed and held |
| Leases and franchises | R-TX-RENT-LESSEE, R-TX-LEASE-INCOME, R-TX-FRANCHISE-INCOME | cat 8, 13, 14; controllers apply the Appendix A boundary to these spend proxies |
| Travel and commuting | R-TX-TRAVEL-GUEST, R-TX-TRAVEL, R-TX-COMMUTING | cat 6, cat 7; guest travel held |
| Waste and water | R-TX-WASTE, R-TX-SPLIT-WATER, R-TX-SPLIT-PREMISES, R-TX-SPLIT-NO-LINES | cat 5; combined charges split |
| Purchased goods and services | R-TX-SMALL-EQUIP-EXPENSED, R-TX-CAT1, R-TX-CAT1-LOW-SPECIFICITY | cat 1; low-specificity services need NACE agreement |
| Activity | R-ACT-* | cat 4, 5, 6, 7, 9 (not paid by the company, whoever else paid), 12; company vehicles and fuel by ownership, lease type and approach |
| Product | R-PRD-* | cat 10, 11; cat 12 for every sold product; cat 9 unless the company pays distribution to the end customer |
| Asset | R-AST-* | cat 8, 13, 14 or not applicable by lease direction, lease type and approach (6.6) |
| Investment | R-INV-IN-BOUNDARY, R-INV-HOLDING | cat 15; consolidated investees not applicable |
| Supplier | R-SUP-* | default category of a supplier relationship; energy suppliers split into Scope 1 (gas, fuel) and Scope 2 |
The file holds 90 rules. Rule identities are stable; a semantic change to a rule is a new ruleset version (new CRID) under ZRR section 9.
6.4. Split rules
Before calculating any amount-based split, all invoice lines—including excluded and unmatched lines—must use the same currency. If the envelope contains an amount, its currency must match that currency. A mismatch rejects the split before arithmetic; the reference implementation raises ValueError and emits no assignment. When the optional envelope amount is absent, uniform line currency is sufficient. This guard performs no exchange-rate conversion.
SPLIT-WATER-01, SPLIT-PREMISES-01 and SPLIT-FREIGHT-CUSTOMS-01 classify each invoice line by governed keyword lists (Norwegian, Swedish and English). A line rule either assigns a category or excludes the line with a reason (customs duties, NA-CUSTOMS-DUTY). When an envelope amount is supplied, the sum of absolute line amounts must equal its absolute value in the same currency; mismatches are rejected before classification. Shares are fractions of the total line amount; excluded lines count toward coverage, produce no child, and are recorded as evidence.split.excluded_share, so a split may have a single child when the rest is excluded. If the matched lines cover less than s3po.split_min_line_coverage of the invoice amount, or a single category results with nothing excluded, the envelope is held (HOLD-SPLIT-INCOMPLETE). Each child envelope re-enters the Post Office carrying parent_envelope_id and the split rule, is assigned at the parent's tier, and routes on its own.
Generated amount-based shares use six decimal places. After rounding coverage, excluded share and preceding children, the final child in ascending (category, direction) order receives the exact remaining share. The recorded child shares plus excluded share therefore equal recorded coverage. If rounding produces a non-positive or greater-than-one child share, the split is held rather than emitting an invalid allocation. Manual overrides must already reconcile and are never silently adjusted.
6.5. Product fan-out
A sold product contributes to several downstream categories at once: distribution, retail and storage not paid by the company (cat 9), processing (cat 10), use (cat 11) and end of life (cat 12). Every sold product has an end of life, so cat 12 applies whether or not end-of-life routes are known; without routes, S3-C12 uses default disposal scenarios (Technical Guidance ch. 12). Cat 9 applies unless the company pays distribution all the way to the end customer; an unknown payer is included and screened by S3-C09. The product adapter collects every matching rule and emits SPLIT with rule FANOUT-PRODUCT-01: one child per distinct (category, direction), each with share 1.0, because each life-cycle stage applies to the full quantity sold. Alternative rules for the same category contribute evidence to one child, never duplicate allocations. If only one distinct category/direction remains, the result is ASSIGNED. All matching rule IDs are retained in the sorted evidence.ruleset.rule_ids array (single-rule non-product decisions retain rule_id); the two representations are mutually exclusive, and child identities derive from the category/direction rather than the matched rule. The confidence is the lowest of the matching rules.
6.6. Leased assets and the consolidation approach
Where a leased asset's emissions belong depends on who leases it, the lease type and the client's consolidation approach (GHG Protocol Scope 3 Standard, Appendix A). The rules implement both tables; the consolidation approach is read from reporting_context.consolidation_approach.
Lessee
| Lease type | Operational control | Financial control | Equity share |
|---|---|---|---|
| Operating | Scope 1/2 (NA-IN-SCOPE12 for the asset; its fuel and energy reroute to Scope 1/2) | cat 8 (asset, fuel and energy) | cat 8 |
| Finance | Scope 1/2 | Scope 1/2 | Scope 1/2 |
Lessor
| Lease type | Operational control | Financial control | Equity share |
|---|---|---|---|
| Operating | cat 13 | Scope 1/2 (NA-IN-SCOPE12) | Scope 1/2 |
| Finance | cat 13 | cat 13 | cat 13 |
When the lease type or, under financial control or equity share, the tenure of premises is unknown, the rule proposes the most common outcome below the threshold and holds. Lease payments and lease income on the ledger (rent_*, leasing_income) are spend proxies: the Post Office assigns them cat 8 or cat 13, and the controllers S3-C08 and S3-C13 apply the same tables as boundary checks (EXCL-IN-SCOPE12).
7. MAP Tier Datasets
Equal-specificity NACE matches: among version-compatible longest-prefix matches, conflicting outcomes, categories or directions produce HOLD-CONFLICTING-SIGNALS. Matches that agree use the lowest confidence, still capped by s3po.map_confidence_ceiling. Supplier-code and mapping-entry order confer no priority. When confidence also ties, lexical mapping-key order selects the evidence key only; it does not change the decision.
Category maps (config/system/scope3/schemas/category-map.schema.v1.json) map an external classification key to an outcome, by longest prefix.
7.1. NACE revisions
NACE Rev. 2.1 applies from 2025 (SN2025 in Norway, SNI 2025 in Sweden) and moves section letters — telecom and IT from J to K, finance from K to L, real estate from L to M, professional services from M to N, administrative services from N to O — while keeping most division and group numbers. Keyed on Rev. 2 letters, Rev. 2.1 supplier codes would mostly stop matching without any error. Therefore:
- NACE keys and supplier codes are numeric, without section letter (
49.41, notH49.41); - every supplier code carries its revision (
nace_version), required by the envelope schema; - map entries whose codes changed between revisions are restricted to the revision they were confirmed for (
versions: ["2"]); the MAP tier only uses entries valid for the supplier's revision; - rule-level NACE prefixes (energy and fuel guards) use codes common to both revisions where known; Rev. 2.1 equivalents of the restricted codes are open item 6.
7.2. Maps
| Map | File | Status | Used for |
|---|---|---|---|
| NACE Rev. 2 / 2.1 | category-maps/nace.json | 45 entries, draft; 7 restricted to Rev. 2 | supplier NACE from E-C-O enrichment: low-specificity accounts, unmapped accounts, corroboration, supplier adapter |
| UNSPSC | category-maps/unspsc.json | contract, empty | invoice-line codes from e-invoicing (Peppol BIS) connectors |
| CN | category-maps/cn.json | contract, empty | product and import lines (shared with CBAM work) |
| Waste treatment | category-maps/waste-treatment.json | contract, empty | EWC and R/D codes via WST-CLASS |
NACE entries whose Scope 3 meaning is ambiguous carry deliberately low confidence so they never decide alone: car rental (77.11) can be business travel or a long-term lease; vehicle fuel retail (47.3) depends on who owns the vehicle; real-estate rental (68.2) depends on lease type and approach; universal postal services (53.1) carry parcels (cat 4) as well as letters; remediation (39) is a purchased service rather than treatment of own waste.
8. AI Tier
The AI tier exists to make a held envelope cheaper to review, not to classify it.
| Aspect | Rule |
|---|---|
| When | only when no rule or map candidate exists and the ladder has not stopped on a conflict |
| Gateway | executed through AI-DIAL, the governed, region-bounded AI execution gateway; no direct model calls |
| Input allow-list | description_text, invoice-line descriptions, supplier name and NACE, account class, adapter, amount and currency, reporting country. No personal data; traveller names and free-text fields matching personal-data patterns are removed before the call |
| Output contract | strict JSON: proposed outcome, category, direction, model confidence, rationale; anything else is discarded and the envelope is held with HOLD-NO-DECISION |
| Confidence | min(model confidence, s3po.ai_confidence_cap); the parameter-set invariant guarantees the cap is below every auto-accept threshold |
| Outcome | always HOLD with HOLD-AI-PROPOSAL; the proposal is the suggested outcome |
| Evidence | gateway, model and policy references, prompt hash, proposal, capped confidence, rationale |
| Replay | RECORDED — the stored proposal is the replay artifact; it is never regenerated |
9. Assignment Artifact
9.1. Identity
ARTIF-ADENGINE-SCOPE3-CATEGORY-ASSIGNMENT, identifier type S3AID. The identifier body is the first 26 Crockford base-32 characters of the SHA-256 of the idempotency key (9.3). The same inputs always produce the same identifier, which makes classification idempotent and replay EXACT by construction.
9.2. Content
The normative schema is schemas/mice/scope3/s3po-category-assignment.v1.schema.json. In summary:
| Group | Fields |
|---|---|
| Identity | assignment_id, envelope_id, envelope_hash, adapter, eco_id |
| Decision | outcome, category, direction, sub_activity, children (for SPLIT), reason_code, suggested_outcome |
| Basis | tier, confidence, threshold_in_force |
| Evidence | parameter-set version; discriminators used; account class and its resolution (chart, version, match, verified, confidence); ruleset CRID, content hash and rule id; map id, version and key; split rule and line coverage; AI record; override record; upstream assertion |
| Engine | MEID, CMI, version |
| Lineage | created_at, supersedes, restatement_cause |
The schema enforces the invariants that matter for assurance: AI_PROPOSED and NONE tiers can only produce HOLD; a RULE tier must cite a ruleset; a MAP tier must cite a map; a HUMAN_OVERRIDE tier must carry the override record; HOLD and NOT_APPLICABLE must carry a reason code.
9.3. Idempotency key
envelope_hash
| ruleset content hash
| category-map versions
| parameter-set version
| account-class resolution (chart id, chart version, match, verified)
| human_override (if any)
| resolved per-client/per-adapter threshold
| canonical recorded AI proposal content hash (AI_PROPOSED), otherwise no-ai-proposal
AI evidence retains the complete uncapped recorded_proposal, its canonical recorded_proposal_hash, and the prompt hash when supplied. The capped decision confidence remains separate. threshold_in_force records the resolved threshold used in the key.
Re-running with an identical key returns the existing assignment. A change to any element produces a new assignment that supersedes the old one (section 10).
10. Re-classification and Delta Events
An assignment is immutable. When an element of its idempotency key changes, affected envelopes are re-classified and the new assignment supersedes the old one with a restatement cause:
| Cause | Trigger | Scope of re-run |
|---|---|---|
RULESET_REVERSION | new ruleset version activated | envelopes whose adapter has a changed rule, for open periods and any period the client re-opens |
MAPPING_REVERSION | category map re-versioned | envelopes that consulted the map |
CHART_MAPPING_REVERSION | client chart mapping or its seed re-versioned, or a client mapping verified | the client's envelopes on affected accounts |
PARAMETER_REVERSION | parameter set re-versioned | envelopes whose decision crossed a changed threshold or cap |
HUMAN_OVERRIDE | quarantine resolution | the envelope, plus any promotion scope (11.3) |
ENVELOPE_REVISION | source record revised | the new envelope |
Every re-run that changes at least one outcome emits one comp.S3-PO.EVENT.ASSIGNMENT_DELTA.v1_0 event per client and cause, listing each changed envelope with its prior and new outcome. Controllers and S3-SUM consume the event to restate; S3-SUM records it in its restatement log, and ESGX consumers receive it as restatement propagation. Re-runs that change nothing emit nothing.
Closed reporting periods are re-classified only on an explicit restatement decision; the delta event then carries the affected periods.
11. Routing, Review and Promotion
11.1. Routing
The Post Office stamps; ZSSR routes (S3-ARCH D4). The routing ruleset code/rulesets/draft/scope3/zssr-s3po-routing.ruleset.json applies to comp.S3-PO.OUTPUT.CATEGORY_ASSIGNMENT.v1_0:
| Condition | Next | Operation |
|---|---|---|
ASSIGNED, category N | comp.S3-C0N.ENGINE.CORE (two-digit N) | COMPUTE |
SPLIT | each child envelope back to S3-PO | ENRICH (fan-out) |
REROUTE_SCOPE1 | comp.S1-CON.ENGINE.CORE | COMPUTE |
REROUTE_SCOPE2 | comp.S2-CON.ENGINE.CORE | COMPUTE |
NOT_APPLICABLE | none | ARCHIVE |
HOLD | vera.TG-QUARANTINE-MANAGER.ENGINE.CORE | MANUAL_REVIEW |
| anything unmatched | vera.TG-QUARANTINE-MANAGER.ENGINE.CORE | MANUAL_REVIEW (fail safe) |
Every outcome matches exactly one condition (test_routing_is_exhaustive_and_unambiguous). Target CMIs are pinned at registration and confirmed against zar.cmi_registry before activation.
11.2. Review round trip
A held assignment becomes a quarantine record in TG-QUARANTINE-MANAGER, which already provides review status, evidence requirements, remediation and replay hooks (S3-ARCH D5). The reviewer sees the envelope, the evidence, the hold reason and the suggested outcome, and resolves with one of:
| Reason code | Decision |
|---|---|
OVR-CONFIRM-PROPOSAL | accept the suggested outcome |
OVR-CORRECT | assign a different outcome or category |
OVR-SPLIT | split manually with shares |
OVR-NOT-APPLICABLE | mark not applicable with a reason |
OVR-REROUTE | reroute to Scope 1 or 2 |
The resolution re-enters the Post Office as an envelope with human_override (actor, reason code, reason text, prior assignment id, decision). The decision is validated by outcome before classification: ASSIGNED requires category and direction; HOLD and NOT_APPLICABLE require their corresponding reason code; reroutes carry only the outcome; SPLIT requires validated children and a split evidence record. A single-child split additionally requires a positive excluded share. Unknown or incompatible decision fields are rejected. Schema validation is followed by semantic validation before classification or persistence: manual split child shares plus excluded share must equal line coverage exactly using the recorded decimal values. Persisted override assignments must retain actor, reason, promotion scope and prior assignment; supersedes must equal that prior assignment identity, checked by validate_assignment_semantics after schema validation. EXPLICIT assignments must retain the complete upstream assertion. It never bypasses the Post Office, so every outcome — human or automatic — is an assignment artifact with one evidence model.
11.3. Promotion
A reviewer may promote a decision beyond the single envelope, through governed change:
promote_to | Effect |
|---|---|
envelope_only | this envelope only (default) |
client_account_mapping | writes or corrects the client chart-mapping entry for the account, re-versioning the client mapping (cause CHART_MAPPING_REVERSION) |
client_supplier_rule | records a client-scoped supplier default (supplier adapter), consulted as an EXPLICIT assertion on that supplier's future envelopes |
Promotion is how the review queue shrinks over time: each accountant decision on a recurring pattern becomes governed data, not a repeated click. Promotions never write to the global ruleset or to seed charts; those change only through ZAYAZ governance.
12. Governed Parameters
The Post Office reads these keys from the governed parameter set config/system/scope3/parameters.json (S3-ARCH D8). Values are administered by ZAYAZ administrators only and never exposed to clients or users.
| Key | Used in | Seed value |
|---|---|---|
s3po.ai_confidence_cap | AI tier (8) | 0.60 |
s3po.auto_accept_threshold_min | threshold floor (5.2) | 0.90 |
s3po.auto_accept_threshold_default | threshold without client policy (5.2) | 0.90 |
s3po.map_confidence_ceiling | MAP tier (7) | 0.95 |
s3po.unverified_mapping_confidence_cap | unverified chart mappings (4.4) | 0.80 |
s3po.split_min_line_coverage | split rules (6.4) | 0.95 |
The set declares its invariants, among them that the AI cap and the unverified-mapping cap are below the threshold floor. scripts/scope3/validate_scope3_config.py checks every Scope 3 configuration file against its schema and checks these invariants; a set that violates an invariant cannot be activated.
13. Worked Examples
Every example below is an executable test in scripts/scope3/tests/test_s3po_reference.py, run against the reference implementation and validated against both the envelope and the assignment schema.
13.1. Freight and customs
Freight account. NOK 12,400 posted to NS 4102 account 6100 (Frakt og transportkostnad), supplier NACE 49.41 (Rev. 2), verified client mapping.
- Account class
freight_purchased(resolution confidence 1.0, verified) →R-TX-FREIGHT→ASSIGNED cat4, upstream, confidence 0.97, tierRULE. - On an unverified mapping the same posting is capped at 0.80 and held with
HOLD-UNVERIFIED-MAPPING, suggestion cat 4 — unless the supplier's NACE49.41(cat 4, 0.92) agrees, in which case it is assigned at 0.92 with tierMAP. A Rev. 2.1 supplier code49.41corroborates the same way, because that entry is valid in both revisions.
Freight inside cost of goods, with duty. NOK 12,400 on NS 4102 account 4060 (Frakt, toll og spedisjon), lines "Frakt Hamburg-Oslo" (10,000) and "Toll" (2,400).
- Class
freight_and_customs_combined→R-TX-SPLIT-FREIGHT-CUSTOMS→SPLIT-FREIGHT-CUSTOMS-01. - One child, cat 4, share 0.806452; the duty line is excluded (
excluded_share0.193548). Cat 4 spend no longer includes customs duty. - Without invoice lines: cat 4 proposed at 0.88 and held; the accountant confirms once and promotes to the client mapping when the account holds no duties.
13.2. Water and wastewater on one invoice
NOK 10,000 on NS 4102 account 6320 (Renovasjon, vann, avløp), lines "Vann, fastledd og forbruk" (6,200) and "Avløp" (3,800).
- Class
premises_services_combined→R-TX-SPLIT-PREMISES→SPLIT-PREMISES-01. - Children: cat 1 share 0.62, cat 5 share 0.38; line coverage 1.0.
- Without invoice lines:
HOLD-SPLIT-NO-LINES. With lines that cannot be classified ("Fastavgift" 90 %):HOLD-SPLIT-INCOMPLETE, coverage 0.10.
13.3. Vehicle fuel
NOK 3,100 on NS 4102 account 7000 (Drivstoff).
- UOM says the reporting company
OWNSthe vehicle →R-TX-FUEL-VEH-OWNED→REROUTE_SCOPE1. - Operating-leased vehicle:
REROUTE_SCOPE1under operational control,ASSIGNED cat8under financial control or equity share; finance-leased: Scope 1 under every approach (6.6). - Short-term rental car on a business trip → cat 6. Employee's private car, purpose unknown → cat 6 proposed and held.
- Ownership unknown →
R-TX-FUEL-VEH-DEFAULTproposes Scope 1 at 0.85 → heldHOLD-BELOW-THRESHOLDwith the suggestion. Registering the fleet in UOM removes these holds.
13.4. Unclassifiable line
NOK 3,000 on account 7790 (Annen kostnad), description "consulting Q3", supplier without NACE.
- Class
other_unspecified: no rule, no map. The AI tier proposes cat 1 at 0.88, capped to 0.60 →HOLD-AI-PROPOSAL. - The accountant confirms with
OVR-CONFIRM-PROPOSALand promotes toclient_supplier_rule. The override envelope re-enters, is assigned cat 1 with tierHUMAN_OVERRIDE, and supersedes the held assignment.
13.5. Business flight
Activity envelope: air_travel, purpose business, traveller employee → R-ACT-TRAVEL-BUSINESS → ASSIGNED cat6 → S3-C06, which invokes the transport kernel K4; K4 executes the air leg through ATME (S3-ARCH 7.2, 12.5).
13.6. Boundary cases
| Case | Outcome |
|---|---|
| Outbound freight paid by the reporting company (activity) | cat 4 |
| Outbound distribution paid by the customer or a third party (activity) | cat 9, downstream |
| Explicit cat 9 asserted on a ledger line | HOLD-CONFLICTING-SIGNALS |
| BAS 1240 debit (vehicle acquired) | cat 2 |
| BAS 1220 debit from construction in progress (contra class capital) | NA-INTERNAL-TRANSFER |
| BAS 1220 supplier credit note | cat 2 (negative) |
| BAS 1249, 1119 (accumulated depreciation) | NA-ACCOUNT-CLASS |
| BAS 1240 credit (disposal) | NA-ASSET-DISPOSAL |
| BAS 5621 truck fuel, truck owned | REROUTE_SCOPE1 |
| BAS 5690 other vehicle costs, no NACE | HOLD-NO-DECISION |
| NS 4102 6200 electricity, operational control | REROUTE_SCOPE2 |
| Same, financial control, premises operating-leased | cat 8 |
| Same, financial control, tenure unknown | Scope 2 proposed, held |
NS 4102 6340 (Lys, varme), supplier NACE 35.30 | REROUTE_SCOPE2 |
| Same account, no NACE | HOLD-NO-DECISION |
Membership account (cat 1, low specificity) with supplier NACE 49.41 (cat 4) | HOLD-CONFLICTING-SIGNALS |
Diesel invoice from a fuel retailer (NACE 47.30, Rev. 2) posted to freight account 6100 | HOLD-CONFLICTING-SIGNALS (R-TX-FREIGHT-FUEL-SUPPLIER); the reviewer reroutes to Scope 1 |
Taxi supplier 49.32 on a residual account, Rev. 2 / Rev. 2.1 | cat 6 / HOLD-NO-DECISION (entry confirmed for Rev. 2 only) |
| Purchase from a group company | NA-INTRA-GROUP |
| Sold energy-using product, end-of-life route, customer-paid distribution | SPLIT fan-out to cat 9, 11, 12 |
| Sold product, no end-of-life data, company pays distribution to the end customer | cat 12 (default disposal scenarios in S3-C12) |
| Leased assets, every lease type and approach | Appendix A matrix (6.6) |
| Franchise as franchisor / listed equity holding / consolidated investee | cat 14 / cat 15 / NA-INTRA-GROUP |
14. Error Model
Errors are distinct from holds: a hold is a decision not to decide; an error means the engine could not evaluate.
| Code | Cause | Effect |
|---|---|---|
S3PO_ENVELOPE_SCHEMA_INVALID | envelope fails its schema | rejected; nothing assigned |
S3PO_UNKNOWN_ACCOUNT_CLASS | resolution returned a class not in the registered vocabulary | rejected; configuration finding raised |
S3PO_CHART_NOT_CONFIGURED | transaction envelope for a client with no chart mapping | rejected until onboarding sets the chart |
S3PO_RULESET_UNAVAILABLE | the active ruleset cannot be resolved or its signature fails | engine refuses to run |
S3PO_PARAMETER_SET_INVALID | the parameter set fails schema or invariants | engine refuses to run |
S3PO_SPLIT_RULE_UNDEFINED | a rule names a split rule the ruleset does not define | rejected; ruleset finding raised |
S3PO_AI_RESPONSE_INVALID | the AI gateway returned output outside the contract | proposal discarded; envelope held HOLD-NO-DECISION |
Every error carries the engine CMI short code, the envelope id and hash, and the configuration versions in force.
15. Replay and Audit
| Tier | Replay (TG-RP) | Reproduced from |
|---|---|---|
HUMAN_OVERRIDE | EXACT | the override record |
EXPLICIT | EXACT | the upstream assertion and its evidence reference |
RULE | EXACT | envelope, ruleset content hash, account-class resolution, parameter-set version |
MAP | EXACT | envelope, map version and key, parameter-set version |
AI_PROPOSED | RECORDED | the stored proposal |
Because the assignment identifier derives from the idempotency key, an auditor can recompute it: same inputs, same identifier. The lineage chain from a Scope 3 total runs S3-SUM → category result → kernel execution and factor → assignment → envelope → ACF source record, with each engine's CMI short code in the USO tail.
16. Dependencies and Interfaces
| Dependency | Use |
|---|---|
ACF connectors and ACF-GOVERNED-CONNECTOR-SCHEMA-V1 | canonical source records, identity resolution (ECO, EBU, EBP), ACF data-quality levels, semantic resolution of activity data |
UOM | ownership, lease and operational-control relationships at the effective date |
SUPP-ONBOARD and E-C-O | supplier identity, NACE, value-chain role |
ZRR | the classification ruleset |
ZSSR | routing of assignments |
TG-QUARANTINE-MANAGER | review of held assignments |
AI-DIAL | the AI tier |
config/system/scope3/ | account classes, chart mappings, category maps, parameter set |
Consumers: the fifteen category controllers, S1-CON, S2-CON, S3-SUM (restatement and unclassified residual), the ESGX/PCAF profile, Watchtower and ledger tagging.
17. Files and Registrations
| Path | Content | Validated by |
|---|---|---|
config/system/scope3/account-classes.json | 54 account classes | schema + validator |
config/system/scope3/chart-mappings/ns4102.json, bas.json | seed charts (65 and 144 entries) | schema + validator + 35 resolver regression cases |
config/system/scope3/category-maps/nace.json, unspsc.json, cn.json, waste-treatment.json | MAP-tier datasets | schema + validator |
config/system/scope3/parameters.json | governed parameter set | schema + invariants |
config/system/scope3/chart-mappings.json, category-maps.json | family indexes, registered in the registry manifest | own index schemas + validator (index must match the directory) |
config/system/scope3/schemas/*.schema.v1.json | six configuration schemas (classes, chart mapping, category map, parameters, two indexes) | JSON Schema 2020-12 |
schemas/mice/scope3/*.schema.json | envelope, assignment, delta event | JSON Schema 2020-12 |
code/rulesets/draft/scope3/s3po-scope3-category-classification.ruleset.yaml | classification ruleset | schemas/zar/ruleset.v1.schema.json, CRID grammar |
code/rulesets/draft/scope3/zssr-s3po-routing.ruleset.json | routing ruleset | exhaustiveness test |
scripts/scope3/ | config validator, account-class resolver, reference implementation, registration script, tests | 46 tests |
registrations/ | registry entries for the artifact type, S3AID and the manifest | applied by scripts/scope3/apply_registrations.py; registry integrity passes on both decision paths |
Registrations required before activation:
- Document ID
S3-PO— generated intoconfig/system/acronyms.jsonfrom this file. - MEID
MEID_GHG_CLASSIFY_SCOPE3inzar.meid_registry, with domainGHGand capabilityCLASSIFY. - Artifact type
ARTIF-ADENGINE-SCOPE3-CATEGORY-ASSIGNMENTinconfig/system/artifact-types.json. - Identifier type
S3AIDinconfig/system/identifier-types.json. - Registry manifest entries for the parameter set, the account classes, the chart-mapping index and the category-map index (the manifest requires one schema per registry, so each family is registered through its index).
- Module inventory:
MEID_GHG_CLASSIFY_SCOPE3in the Computation Hub micro-engine inventory ofconfig/system/omr.modules.json. - CSI bindings for the three signal families in
zar.signal_csi_binding. - ZRR registration of the classification ruleset; ZAR registration of the routing ruleset.
18. Open Items
| # | Item | Owner |
|---|---|---|
| 1 | The artifact-type registry schema accepts only hyphenated signal names ([A-Z0-9-]+), while the Canonical Identifier Architecture requires UPPER_SNAKE names (CATEGORY_ASSIGNMENT). CMPS-001's examples also use hyphens. The registry schema pattern needs [A-Z0-9_-]+, or CIA needs amending. scripts/scope3/apply_registrations.py --allow-cia-csi applies the first option together with the artifact and identifier types; without the flag both are left out and registry integrity still passes. | CTO decision |
| 2 | UOM has no franchise relationship type; franchise role is read from the asset register until one is registered. | UOM owner |
| 3 | Seed charts are unverified by design. The first client on each seed should be verified line by line and its corrections folded back into the seed. | Accounting partner |
| 4 | UNSPSC, CN and waste-treatment maps are contracts without entries. Populate when the first connector delivering those codes is live. | Data |
| 5 | atme.radiative_forcing_enabled is unset in the parameter set; it must be decided before ATME is activated (not a Post Office dependency). | CTO decision |
| 6 | NACE Rev. 2.1 equivalents for the seven Rev. 2-only map entries (46.71, 47.3, 49.31, 49.32, 49.39, 52.29, 58.2) and for the rule-level fuel guards, from the official Rev. 2 → Rev. 2.1 correspondence table. | Data |
| 7 | Lease type (operating or finance) must be captured in the lease register for every leased asset and vehicle; without it, Appendix A cases are proposed and held (6.6). | Onboarding |
Currency-conversion follow-up
Add a shared monetary-input normalization boundary before kernel execution. Preserve native amounts and currencies alongside normalized amounts and a frozen exchange-rate reference (fx_rate_id). Record provider, effective date, calculation currency, rate and rounding policy; replay must reuse that snapshot. Current valuations may use current rates, while historical transactions use the reporting policy's effective date. Convert monetary display outputs separately; do not convert quantities, percentages or emissions. The shared boundary is specified in ZX-KISMET-01, with a provider-neutral reference implementation in schemas/kismet/reference/currency.py. Production provider selection and host integration remain separate deployment work. This engine continues rejecting mixed-currency input: its caller must normalize first, retain the native values and frozen evidence, and reconcile the envelope total to the normalized lines.