--- name: emem-eudr-due-diligence description: Produces a signed, Annex II shaped Due Diligence Statement under the EU Deforestation Regulation (EU 2023/1115) for one or more production plots with emem, and explains what it proves and what it leaves to the operator. Checks each plot against the JRC GFC2020 forest baseline and Hansen Global Forest Change loss year at the 2020-12-31 cut-off, cross-checks JRC TMF, and grades how well the inputs support the verdict. Use when a supplier, importer or auditor asks whether a cocoa, coffee, soy, palm, rubber, cattle or wood plot is deforestation-free, or needs per-cell evidence for an Article 12 record. --- # emem-eudr-due-diligence > **Network use.** The commands in this skill send and receive JSON (and, where a step says so, an image or a raster file) to `https://emem.dev` only, the service the plugin's MCP server connects to. Nothing they download is executed. This skill ships no scripts. Its commands read no environment variable, key or credential, and the only local files they read are ones an earlier step saved from `https://emem.dev`. `POST /v1/eudr_dds` (MCP `emem_eudr_dds`) evaluates plots against the Regulation's forest definition (10 % canopy, 0.5 ha, 5 m) and returns a signed envelope an operator can keep as evidence. It covers the geolocation and deforestation parts of Annex II. It does not cover legality (Article 9(1)(b)) or forest degradation (Article 2(7)), and the response says so in `legality_disclaimer` and `degradation_disclaimer`. Pass both on. ## The request Call `emem_eudr_dds` with: ```json {"operator": {"name": "Example Cocoa Importer"}, "plots": [{"plot_id": "CIV-001", "geometry_geojson": {"type": "Point", "coordinates": [-5.5471, 6.8276]}, "country_of_production": "CIV", "commodity_hs": "180100", "quantity_kg": 1200}]} ``` `emem_eudr_dds` is outside the short tool list the plugin's MCP server shows. The server runs it by name through `tools/call`. If your host calls only listed tools, use the REST route. Save the result's JSON text as `dds.json`. The call can take minutes, so send it with a `task` param and poll `tasks/get`. A statement larger than the MCP wire budget (about 24 KB) is refused, not cut, because a partial statement still looks whole. When that happens, or when you have no MCP, send the same body to `POST https://emem.dev/v1/eudr_dds` and allow up to 300 s for the answer. Per plot: `geometry_geojson` (a Polygon for plots over 4 ha; a Point is allowed for 4 ha or less, except cattle, per Article 2(28); or `{"bbox":[w,s,e,n]}`), `country_of_production` (ISO 3166-1 alpha-3), `commodity_hs` (HS-6 or longer, checked against Annex I) and `quantity_kg`. Optional: `request_visual_evidence: true` adds a year-by-year Sentinel-2 NDVI and Sentinel-1 backscatter timeline with scene links, and several minutes of upstream reads. Top level: `cut_off_date` (default `2020-12-31`), `forest_baseline_override` (`jrc_gfc2020_v4`, `hansen_only`, `both`; `jrc_gfc2020_v3` is still accepted), `max_cells_per_plot` (auto-derived from polygon area when omitted). The full schema is `GET https://emem.dev/v1/schemas/eudr_dds.json`. A cold plot can take minutes and can fail with `source_fetch_failed` naming the slow tile. Warm it first with a recall on one cell of the plot: 1. Call `emem_locate` with the plot's coordinates, and keep the `cell64` it returns: ```json {"lat": 6.8276, "lng": -5.5471} ``` 2. Call `emem_recall` with that cell and the forest bands. Read `band` and `value` of each entry in `facts[]`: ```json {"cell": "", "bands": ["jrc_gfc2020.forest_2020", "forest_change.lossyear", "forest_change.treecover2000"]} ``` Over REST, the same bodies go to `POST https://emem.dev/v1/locate` and `POST https://emem.dev/v1/recall`. ## Reading the response ```sh jq '{verdict: .due_diligence_statement.verdict, signable: .traces_nt_envelope.statementOfComplianceSignable, review_required: .traces_nt_envelope.statementOfComplianceReviewRequired, baseline: .forest_baseline, datasets: .forest_baseline_dataset, plots: [.per_plot_results[] | {plot_id, verdict, failing_area_ha, support: .verdict_support.level, limits: .verdict_support.limits, tmf: .tmf_cross_check | {agreement, review_required, post_cutoff_loss}}]}' dds.json ``` - **Plot verdicts**: `pass`, `fail`, `not_in_scope` (cleared at or before the cut-off, so not forest at the cut-off), `indeterminate`, or `below_mmu` (failing area under the 0.5 ha floor, counted as compliant). `per_cell_verdicts` carries the signed fact cids behind each; quote them in the Article 12 record. - **`forest_baseline_dataset`**: the dataset versions actually read, by name and source. `forest_baseline` names the JRC version its facts were read from (`jrc_gfc2020_v4`), and the fact derivations carry it too (`jrc_gfc2020_v4_pixel@1`); quote the versions from this field. - **`tmf_cross_check`**: JRC TMF deforestation year read on every cell and compared with Hansen after the cut-off (`both`, `hansen_only`, `tmf_only`, `neither`, `agreement`). It is not counted in the verdict. A `tmf_only` loss sets `review_required: true`, because TMF often sees degradation-to-clearance that Hansen misses. - **`verdict_support.level`**: `strong`, `moderate` or `weak`, from how complete the inputs are (share of cells with both baselines, TMF agreement, borderline canopy, and sample spacing against the 71 m side of a 0.5 ha square), each shortfall listed in `limits`. It is not a calibrated probability. - **`traces_nt_envelope`**: the TRACES NT shaped statement. `statementOfComplianceReviewRequired` says when a person must look first. `ddsReferenceNumber` is an emem placeholder; TRACES NT issues the real one. A statement is held for review when any plot has `tmf_cross_check.review_required`, when any plot has `verdict_support.level` `weak`, or when the verdict ran without the JRC baseline (`forest_baseline_computed` is `hansen_only_jrc_unavailable`). The top-level `statement_of_compliance_signable` and the envelope's `statementOfComplianceSignable` use one rule, so they always agree: each is true only for an overall `pass` that is not held for review. `statement_of_compliance_held_because` (envelope: `statementOfComplianceHeldBecause`) lists every cause that applies: `verdict_