The workspace carries a forked xml-sec for one reason, and that reason has never been observed passing a test.
What the fork is for
Cargo.toml:
# Vendored one-constant fix: the published crate hard-caps XML node-sets at
# 65536 and the Italian and French trusted lists carry 65540 and 65541, so
# neither verifies. Reported upstream as structured-world/xml-sec#158 — remove
# this stanza and the fork when that ships.
[patch.crates-io]
xml-sec = { git = "https://github.com/odal-node/xml-sec.git", rev = "7daf6028e08bc17f60ac36833d90c9307ca25449" }
Four and five nodes over a 65,536 ceiling. Without the fork, XMLDSig verification of the Italian and French trusted lists fails — not as a bad signature, but as a canonicaliser that stops before the end of the document.
The gap
The trusted-list fixtures are eu-lotl.xml and fi-trusted-list.xml — the Commission's list of lists, and Finland.
IT and FR are not among them. So:
- the fork's justification rests on a bug report, not on a green test;
- nothing in the suite would notice if the fork stopped being applied;
- and nothing would notice if a future fork rebase reintroduced the cap.
Everything else about the trusted-list chain is tested against real published documents, deliberately and well. This is the one claim in it that is asserted rather than demonstrated.
Why "stopped being applied" is a real failure mode, not a hypothetical
crates/dpp-seal/Cargo.toml requires xml-sec = "0.1.16", and the fork is 0.1.16, so the patch currently satisfies the requirement and applies.
Bump that requirement to "0.1.17" — which is exactly what someone will do the day upstream publishes — and the fork's 0.1.16 no longer satisfies it. Cargo then emits an unused patch warning, not an error, and silently resolves to the registry crate.
If upstream 0.1.17 contains the fix, that is the desired outcome and the stanza should go. If it does not, the cap comes back, and the only symptom is two Member States failing verification. Today nothing distinguishes those two cases.
⚠️ The same mechanism broke the [patch] during the core 0.19.0 repin. It is quiet by design.
Upstream status as of 2026-09-12: xml-sec is still at 0.1.16 on crates.io, published 2026-08-29. structured-world/xml-sec#158 has not shipped, so the fork is load-bearing now and for the foreseeable release.
What to do
1. Add Italian and French trusted lists as fixtures, and assert they verify through a verified LOTL.
Same shape as the existing chain tests: take the pointer for the territory out of the verified LOTL, verify the national document against the certificates that pointer names, assert a VerifiedTrustedList. Nothing new is needed beyond the two documents.
These are the two largest documents in the set, so the fetch cap stated at the call site (1 MiB) is worth re-checking against their actual sizes rather than assumed to cover them.
2. Make the fork's absence go red rather than warn.
The tests in step 1 do most of this: remove the [patch.crates-io] stanza and they should fail. Verify that they actually do before trusting them green — a gate that has never failed is not known to work, and this one has a specific failure to reproduce.
Worth considering alongside: a check that the resolved xml-sec source is the git one, so the diagnostic says "the patch is not applied" rather than leaving someone to infer it from two country-named test failures.
3. Keep the exit condition visible.
The stanza comment already names structured-world/xml-sec#158 as the removal trigger. When it ships, the change is: bump the requirement, delete the stanza, delete the fork — and the step-1 tests are what prove the published crate is genuinely fixed rather than assumed to be.
Sequencing
Blocked. crates/dpp-seal/src/trustlist/ and crates/dpp-seal/tests/fixtures/ do not exist on main — they arrive with #294, which cannot merge until dpp-core 0.20.0 is published and this workspace repins (#296).
The work itself needs nothing from core and could be committed onto the #294 branch beforehand, where the dpp-seal suite already runs green in isolation. That is a judgement call about branch size: it adds two large fixtures and a handful of tests to a branch that is already sizeable and waiting on an external event.
Out of scope
The anchor refresh story. EU_LOTL_ANCHOR pins six SHA-256 digests from OJ notice CELEX 52026XC01944, and a pin nobody refreshes will eventually reject a valid LOTL as NotAnchored — failing closed, looking like an outage. That is a real gap and a different one; #295 already flags it as needing design alongside the verifier. Not folded in here.
The workspace carries a forked
xml-secfor one reason, and that reason has never been observed passing a test.What the fork is for
Cargo.toml:Four and five nodes over a 65,536 ceiling. Without the fork, XMLDSig verification of the Italian and French trusted lists fails — not as a bad signature, but as a canonicaliser that stops before the end of the document.
The gap
The trusted-list fixtures are
eu-lotl.xmlandfi-trusted-list.xml— the Commission's list of lists, and Finland.IT and FR are not among them. So:
Everything else about the trusted-list chain is tested against real published documents, deliberately and well. This is the one claim in it that is asserted rather than demonstrated.
Why "stopped being applied" is a real failure mode, not a hypothetical
crates/dpp-seal/Cargo.tomlrequiresxml-sec = "0.1.16", and the fork is0.1.16, so the patch currently satisfies the requirement and applies.Bump that requirement to
"0.1.17"— which is exactly what someone will do the day upstream publishes — and the fork's0.1.16no longer satisfies it. Cargo then emits an unused patch warning, not an error, and silently resolves to the registry crate.If upstream 0.1.17 contains the fix, that is the desired outcome and the stanza should go. If it does not, the cap comes back, and the only symptom is two Member States failing verification. Today nothing distinguishes those two cases.
[patch]during the core 0.19.0 repin. It is quiet by design.Upstream status as of 2026-09-12:
xml-secis still at 0.1.16 on crates.io, published 2026-08-29.structured-world/xml-sec#158has not shipped, so the fork is load-bearing now and for the foreseeable release.What to do
1. Add Italian and French trusted lists as fixtures, and assert they verify through a verified LOTL.
Same shape as the existing chain tests: take the pointer for the territory out of the verified LOTL, verify the national document against the certificates that pointer names, assert a
VerifiedTrustedList. Nothing new is needed beyond the two documents.These are the two largest documents in the set, so the fetch cap stated at the call site (1 MiB) is worth re-checking against their actual sizes rather than assumed to cover them.
2. Make the fork's absence go red rather than warn.
The tests in step 1 do most of this: remove the
[patch.crates-io]stanza and they should fail. Verify that they actually do before trusting them green — a gate that has never failed is not known to work, and this one has a specific failure to reproduce.Worth considering alongside: a check that the resolved
xml-secsource is the git one, so the diagnostic says "the patch is not applied" rather than leaving someone to infer it from two country-named test failures.3. Keep the exit condition visible.
The stanza comment already names
structured-world/xml-sec#158as the removal trigger. When it ships, the change is: bump the requirement, delete the stanza, delete the fork — and the step-1 tests are what prove the published crate is genuinely fixed rather than assumed to be.Sequencing
Blocked.
crates/dpp-seal/src/trustlist/andcrates/dpp-seal/tests/fixtures/do not exist onmain— they arrive with #294, which cannot merge untildpp-core0.20.0 is published and this workspace repins (#296).The work itself needs nothing from core and could be committed onto the #294 branch beforehand, where the
dpp-sealsuite already runs green in isolation. That is a judgement call about branch size: it adds two large fixtures and a handful of tests to a branch that is already sizeable and waiting on an external event.Out of scope
The anchor refresh story.
EU_LOTL_ANCHORpins six SHA-256 digests from OJ notice CELEX52026XC01944, and a pin nobody refreshes will eventually reject a valid LOTL asNotAnchored— failing closed, looking like an outage. That is a real gap and a different one; #295 already flags it as needing design alongside the verifier. Not folded in here.