vortx-ai/emem/emem-eudr-due-diligence

Claude Code and agent skill by vortx-ai/emem

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Produces a signed, Annex II shaped Due Diligence Statement under the EU Deforestation Regulation (EU 2023/1115) for one or more production plots. It says what it proves and what it leaves to the operator. It checks each plot against the JRC GFC2020 forest baseline and the Hansen Global Forest Change loss year at the 2020-12-31 cut-off. It cross-checks JRC TMF and grades how well the inputs support the verdict. Use when someone asks if a cocoa, coffee, soy, palm, rubber, cattle or wood plot is deforestation-free. Also use it for per-cell evidence for an Article 12 record.

Install

npx vskill@latest install vortx-ai/emem/emem-eudr-due-diligence

SKILL.md

emem-eudr-due-diligence

Use it whenA supplier, importer or auditor asks if a plot of an EUDR commodity is deforestation-free, or needs per-cell evidence for an Article 12 record.
You needFor each plot: a GeoJSON geometry, the country of production (ISO 3166-1 alpha-3), the HS code and the quantity in kg. No key.
You getA verdict for each plot and for the statement, a TRACES NT shaped envelope, the signed fact cids behind each cell, and an Ed25519 receipt.
CallsPOST /v1/eudr_dds (MCP emem_eudr_dds). To warm a cold plot first: POST /v1/locate, POST /v1/recall.
Network use. The commands in this skill send JSON to https://emem.dev and receive JSON from it. https://emem.dev is the service that the MCP server of the plugin connects to. The commands do not execute what they download. This skill ships no scripts. Its commands read no environment variable, key or credential. The only local files that they read are files that an earlier step saved from https://emem.dev.

The endpoint tests each plot against the forest definition of the Regulation: 10 % canopy, 0.5 ha and 5 m. It returns a signed envelope that 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)). The response says so in legality_disclaimer and degradation_disclaimer. Give both to the user.

Step 1: warm a cold plot

A cold plot can take minutes. It can also fail with source_fetch_failed, which names the slow tile. To prevent this, read the forest bands on one cell of the plot first.

Get the cell64 of the plot point. Send this body to POST https://emem.dev/v1/locate and read cell64 in the answer:

json
{"lat": 6.8276, "lng": -5.5471}

This returned defi.zb44d.zaedf.bujI on 7 November 2026. Read the three forest bands at that cell. Send this body to POST https://emem.dev/v1/recall:

json
{"cell": "defi.zb44d.zaedf.bujI", "bands": ["jrc_gfc2020.forest_2020", "forest_change.lossyear", "forest_change.treecover2000"]}

For each entry of facts[] in the answer, read band, value and unit.

On 7 November 2026 it returned jrc_gfc2020.forest_2020 0, forest_change.lossyear 0 and forest_change.treecover2000 20. The MCP tools emem_locate and emem_recall take the same bodies.

For a Point, the statement samples one cell in a box that reaches 0.0001 degrees on each side of the point. That cell can be a neighbour of the cell from locate. On 7 November 2026 the statement read defi.zb44d.zae9f.bujI. The warm-up still helps, because it loads the source tiles, and neighbour cells share them.

Step 2: send the request

Send this body to POST https://emem.dev/v1/eudr_dds and save the answer as dds.json:

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
}]
}

Allow up to 300 s for a cold plot. After step 1, this call answered in less than 1 s on 7 November 2026.

Over MCP, call emem_eudr_dds with the same body. The plugin's MCP server does not list this tool, but tools/call runs it by name. If your host calls only listed tools, use the REST route. A long call over MCP can use a task param and poll tasks/get. The MCP server refuses a statement larger than its wire budget (about 24 KB). It does not cut it, because a partial statement looks complete. In that case, use the REST route.

Fields for each plot
FieldRequiredValue
plot_idyesYour own id for the plot.
geometry_geojsonyesA Polygon for a plot of more than 4 ha, or for cattle. A Point for a plot of 4 ha or less (Article 2(28)). The endpoint also takes {"bbox":[w,s,e,n]}.
country_of_productionyesISO 3166-1 alpha-3, for example CIV.
commodity_hsyesHS-6 or longer. The endpoint checks it against Annex I.
quantity_kgyesThe quantity in kg.
request_visual_evidencenotrue adds a Sentinel-2 NDVI and Sentinel-1 backscatter timeline for each year, with scene links. It adds upstream reads that can take minutes.
Fields at the top level
FieldDefaultValue
operatornone{"name": ...} for the envelope.
cut_off_date2020-12-31The deforestation cut-off.
forest_baseline_overrideJRC with Hansenjrc_gfc2020_v4, hansen_only or both. The endpoint still takes jrc_gfc2020_v3.
max_cells_per_plotfrom the polygon areaThe sample size for each plot.
per_cell_detailrowsrows puts the per-cell rows in the response. anchor leaves them out and keeps per_cell_rows_cid.
per_cell_offsetnonePages the per-cell rows. See step 4.

The request schema is EudrDdsReq in the OpenAPI document at GET https://emem.dev/openapi.json. The response schema is at GET https://emem.dev/v1/schemas/eudr_dds.json.

Step 3: read 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
VerdictMeaning
passNo forest loss after the cut-off on forest that stood at the cut-off.
failForest loss after the cut-off, over at least 0.5 ha.
not_in_scopeThe forest loss on the land came at or before the cut-off, so the land was not forest at the cut-off.
indeterminateThe inputs do not decide the verdict.
below_mmuThe failing area is less than the 0.5 ha floor. It counts as compliant.

per_cell_verdicts gives the signed fact cids behind each cell. Put them in the Article 12 record.

Other fields
FieldWhat it tells you
forest_baseline_datasetThe name, version and source of each dataset that the endpoint read. Quote the versions from this field.
forest_baselineThe JRC version that the facts came from, for example jrc_gfc2020_v4. The fact derivations carry it too (jrc_gfc2020_v4_pixel@1).
tmf_cross_checkThe JRC TMF deforestation year on each cell, compared with Hansen after the cut-off: both, hansen_only, tmf_only, neither and agreement. It does not change the verdict. A tmf_only loss sets review_required: true, because TMF often sees a clearance that started as degradation and that Hansen misses.
verdict_support.levelstrong, moderate or weak. It shows how complete the inputs are. It is not a calibrated probability. Each shortfall is in limits.
sampling_caveatPresent for a Point plot. It says that one cell, about 9.5 m, stands for a plot of up to 4 ha.
traces_nt_envelopeThe TRACES NT shaped statement. ddsReferenceNumber is an emem placeholder. TRACES NT issues the real number.

These inputs set verdict_support.level (verdict_support in lib.rs):

Inputstrongweak
Cells with both the JRC baseline and the Hansen loss year95 % or moreless than 80 %
TMF agreement with Hansen, where TMF reads90 % or moreless than 70 %
Cells within 2 points of the 10 % canopy threshold10 % or lessmore than 30 %
Sample spacing, for a plot of 0.5 ha or more71 m or lessmore than 141 m

A value between the two columns gives moderate. Three more cases give moderate:

  • The plot has one sample cell, for example a Point.
  • The plot is less than 0.5 ha.
  • TMF read no cell, and the plot is within 30 degrees of the equator.
When the endpoint holds the statement for review

The endpoint holds the statement for review when one of these is true:

  • A plot has tmf_cross_check.review_required: true.
  • A plot has verdict_support.level weak.
  • The JRC baseline was not available. forest_baseline_computed is then

hansen_only_jrc_unavailable.

statement_of_compliance_signable at the top level and statementOfComplianceSignable in the envelope use one rule, so they always agree. Each is true only when the overall verdict is pass and the endpoint does not hold the statement for review.

statement_of_compliance_held_because (in the envelope: statementOfComplianceHeldBecause) lists each cause that applies. It is empty when the statement is signable.

CauseReason
verdict_<label>The overall verdict is not pass.
tmf_cross_check_review_requiredTMF saw a loss that Hansen did not see.
verdict_support_weakOne plot has weak support.
jrc_baseline_unavailable_hansen_onlyThe verdict used Hansen only.
Result on 7 November 2026

The Point plot in step 2 (cocoa, Côte d'Ivoire) returned this at 01:06 UTC. A second call at 03:31 UTC returned the same values:

json
{"verdict": "pass", "signable": true, "review_required": false,
"baseline": "jrc_gfc2020_v4",
"datasets": [{"name": "JRC Global Forest Cover 2020", "version": "V4"},
{"name": "Hansen Global Forest Change", "version": "v1.13 (2025)"}],
"plots": [{"plot_id": "CIV-001", "verdict": "pass", "failing_area_ha": 0.0,
"support": "moderate",
"limits": [{"severity": "qualifies", "why": "one point sample: a clearance elsewhere on the plot is not seen"},
{"severity": "qualifies", "why": "the plot is 0.01 ha, under the 0.5 ha minimum mapping unit (Art. 2(4)), so no clearance of that size fits in it and none can fall between samples"}],
"tmf": {"agreement": 1.0, "review_required": false,
"post_cutoff_loss": {"both": 0, "hansen_only": 0, "neither": 1, "tmf_only": 0}}}]}

The one cell read jrc_forest_2020 0, hansen_treecover_2000 20, hansen_lossyear 0 and jrc_tmf_deforestation_year 0, with four fact cids. The receipt signs five fact cids and verified. The datasets lines above leave out the source URLs.

On 28 September 2026 the same plot first failed with source_fetch_failed on a cold Hansen tile. A later call then answered with support strong, while TMF read no cell. The code now lowers the level to moderate for one sample cell and for an unread TMF in the tropics.

Step 4: verify and keep the evidence

The response has a signed receipt over the per-cell fact cids. On a large plot the receipt signs only the first cids, sorted by cid. The response then shows receipt_fact_cids_capped and receipt_fact_cids_total.

Verify the receipt on the server. Build the body from the saved answer:

sh
jq -c '{receipt}' dds.json > verify_req.json

Send verify_req.json as the body of POST https://emem.dev/v1/verify_receipt. Read valid, signature_valid and merkle_proof_valid in the answer.

On 7 November 2026 all three were true. To verify offline, without trust in the responder, use `emem-verify-receipt`.

The responder stores the facts of every sampled cell, also the cells that the response does not show. facts_computed and facts_persisted give the counts, for each plot and in total. Each fact cid in the response resolves at GET https://emem.dev/v1/facts/<cid>, and so does each cid behind per_cell_rows_cid.

Per-cell rows

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 90 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

7-day trend score
0

Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/vortx-ai/emem/emem-eudr-due-diligence/badge)](https://verified-skill.com/skills/vortx-ai/emem/emem-eudr-due-diligence)

Something wrong with this skill or its page? Tell us.