How the engine reaches a per-plot verdict. The data sources, the pipeline, the decision rules, and what the methodology does not claim.
Our implementation choice for the questions Reg. (EU) 2023/1115 asks, not a regulator-approved methodology. The operator stays the duty-bearer under Arts. 4 and 8–12.
The four upstream Earth-observation datasets the engine consults (Hansen GFC, ESA WorldCover, JRC GFC2020, RADD) are served via emem. The open-source Earth-memory protocol. Every band, every cell, every fact is signed upstream and content-addressed; the engine reproduces those signatures verbatim in the DDS receipt so the chain is verifiable end-to-end.
This page explains, in regulator-readable language, exactly what data the engine consults and how it converts those data into the verdict that lands in the Annex II Due Diligence Statement.
For each plot of land in a consignment, the engine answers:
Was this plot deforested on or after 2020-12-31, in the sense of Art. 2(13) of Reg. (EU) 2023/1115?
The output is one of three labels per plot:
signal); the operator is notified to supply additional evidence.
A consignment is "negligible risk" overall when every plot is negligible. If any plot fails, the consignment fails.
The engine consults four open Earth-observation datasets. Each one is cited verbatim in the signed receipt, so anyone can re-derive the verdict on their own machine without trusting our infrastructure.
Authoritative source for annual forest-loss data from 2001 onward. The University of Maryland (Hansen et al.) publishes a global 30-metre raster keyed by year of loss. The product we consume is v1.12 (covering loss years 2001–2024, expected to update annually).
Two bands matter:
treecover2000 (%). Tree-canopy density in the reference year(2000). Used to confirm the cell was forest at the time-zero baseline before the engine inquires about loss.
lossyear (offset from 2000). The year forest cover was lost, if it was. lossyear == 21 means 2021; lossyear == 0 means no loss recorded.
A cell is flagged post-cut-off when treecover2000 > 0 AND lossyear >= 21. The engine carries the raw lossyear value verbatim into the receipt so the auditor sees the integer Hansen returned.
Authoritative source for land-cover class as of 2021. The European Space Agency publishes a global 10-metre raster classifying every pixel into one of eleven classes. Tree cover, shrubland, grassland, cropland, built, bare, snow/ice, permanent water bodies, wetland, mangrove, moss/lichen.
We use WorldCover 2021 because:
pixel was already non-forest in WorldCover 2021, it cannot have been deforested by the engine's evidence window. The loss, if any, pre-dates the cut-off.
WorldCover pixels, so the dominant class is solid to single-pixel noise.
The engine surfaces the WorldCover dominant class per cell in the report's land-cover panel.
The Joint Research Centre's forest baseline at the EUDR cut-off date. JRC GFC2020 v3 (released 2024) is the Commission-funded implementation of what the Regulation considers "forest" on 2020-12-31. It uses a different signal mix than Hansen (Sentinel-1 + Sentinel-2 + Landsat) and a different definition of "forest" (>= 10% canopy cover + >= 0.5 ha + >= 5 m height, the FAO definition the Regulation references).
The engine cross-checks Hansen against JRC GFC2020 for every cell, when the two agree, the verdict is high-confidence. When they disagree, the receipt records both verbatim and the engine emits a "baseline disagreement" trace event so the operator can investigate.
A near-real-time alert layer fused from Sentinel-1 SAR (10 m backscatter, ~weekly revisit) and Sentinel-2 optical (~5-day revisit, weather-permitting) for the tropics. RADD ("Radar for Detecting Deforestation") publishes new alerts within days of the loss event.
The engine uses RADD as a fast-moving signal that supplements Hansen's annual update. A plot that passes the Hansen check today may fail next month if RADD flags new loss; the optional continuous monitoring skill (eudr.monitor.subscribe) re-checks RADD on a cadence and emits a re-attestation event when a new alert appears.
The Regulation requires geolocation in GeoJSON polygons. The engine's pipeline takes that polygon and:
cell64 cells. emem uses a custom 64-bit Hilbert-ordered geospatial code (21 bits latitude, 22 bits longitude) at a canonical resolution of ~9.55 m at the equator. Cells are serialised as four dot-separated base-1024 bigrams (e.g. defi.zb493.xoso.zcb6a) so string prefixes preserve spatial locality. The deployment exposes a single resolution today, migrating toward H3-res-13 (~3.4 m) per emem's published spec.
EMEM_MAX_CELLS_PER_PLOT)from the cell set. The sampling is deterministic. A stratified sweep across the polygon. So re-running the same scenario produces the same evidence.
above. emem returns each signal as a content-addressed fact with a CIDv1 anchor so the engine never has to trust an opaque API response. Every signal is verifiable by re-deriving the CID from the canonical bytes.
logic described above.
The Regulation cares about the polygon's status, not any one pixel's. We could in principle aggregate at polygon level (one "forest fraction" number across the whole plot). We deliberately don't, because:
triggered the flag, not a single aggregate. A per-cell receipt lets the operator look at the exact sub-area, send a field worker, and resolve the question.
loss inside a 100-hectare plot becomes a 1% noise floor; per-cell sampling surfaces the same loss as one flagged cell among many.
identifier verbatim, so the auditor can fetch the same cell from emem.dev next year and compare.
The trade-off is that per-cell evidence is verbose. The receipt for a 4-hectare plot may carry 32 cells × 4 signals = 128 fact CIDs. That is the verbosity at the EUDR's evidentiary bar.
The signed receipt records the pipeline as a 7-stage DAG. Each stage emits structured trace events that flow into the receipt's stage_traces block so the auditor sees exactly what ran and how long it took.
| Stage | Inputs | Outputs |
|---|---|---|
| 1. geo | scenario JSON | per-plot bbox, centroid, cell64, smallholder flag |
| 2a. forest | per-plot cells | per-cell Hansen + ESA + JRC + RADD facts |
| 2b. snapshots | per-plot bbox + centroid | per-cell NDVI / SAR / JRC GSW + per-plot soil / weather / elevation |
| 3. legality | country, commodity, supplier | tier (Implementing Reg. 2025/1093), simplified-DD flag |
| 4. tenure | (plug-in module) | tenure-rights findings or empty |
| 5. risk | forest + legality | composite risk score 0–1 + verdict label |
| 6. dds | risk + scenario | Annex II JSON document |
| 7. settle | DDS verdict | settlement record (free-tier: no charge) |
The DAG is fully observable. Calling GET /a2a/tasks/<id>/events streams the stage start/done events in real time over SSE; the final receipt carries the same events as a structured array.
The composite verdict label is derived from the per-cell evidence plus the country tier. The rules are:
sampled cell with lossyear >= 21 flips the plot. This is the strongest signal and the cheapest one to verify.
RADD picks up loss before Hansen's annual update lands.
Hansen says "no loss" but JRC says "non-forest in 2020", the plot is flagged for review. The receipt carries both verbatim.
has no coverage for the region (rare at the equator, common near the poles). The operator is notified to supply additional evidence.
Simplified due diligence applies; the operator can skip the Art. 10/11 risk-assessment + mitigation steps.
The DDS is generated but the operator still owes the Art. 10/11 risk-mitigation paper trail under the standard regime.
The threshold for "any cell" is one cell. We do not aggregate. A 1-of-32 flag is still a flag.
Hansen + RADD + JRC are agnostic. They detect canopy loss, not who or what removed the trees. The Regulation in turn defines deforestation in land-use terms, not driver terms, so this is acceptable.
land. Tenure, land registration, FPIC, and indigenous-rights questions are out of scope of this baseline. A partner provider can plug in via the LegalityProvider trait.
claims. Those belong in a separate audit; the Regulation references them in Art. 2(40) but does not require this engine to adjudicate them.
2020-12-31. That land is not the Regulation's concern.
| Source | Update | Engine impact |
|---|---|---|
| Hansen GFC | Annual (typically March of year N+1) | Receipt's Hansen vintage is recorded; new compiles use the new vintage. |
| ESA WorldCover | New version expected 2025+ | Engine pins WorldCover 2021 for the EUDR baseline; new versions are evaluated before adoption. |
| JRC GFC2020 | One-off baseline at 2020-12-31 | Static; no update planned. |
| RADD | Weekly to sub-weekly | The continuous-monitoring skill re-checks each filed plot monthly by default. |
| Country tier | When Commission publishes a new Implementing Reg. | Engine reads from data/country_benchmarks_2025_1093.json; deployer can hot-edit without restart. |
Every receipt the engine signs carries:
cell64 identifiers of every sampled cell.as_of date (Implementing Regulation reference).An auditor can take a receipt issued today, re-fetch the same cells from emem.dev one year later, and recover the same per-cell facts. Hansen's annual update may add a new loss year (which would change a future compile) but the historical facts are immutable. That's the point of content-addressed evidence.