Three obligations from the toy and detergent passport regimes bind the surface that serves a passport to a consumer — the resolver and the QR render path — rather than the data model. Two are absent; one holds by accident.
1. ⬜ The Safety Gate link must be displayed on access — toys Art. 19(11)
Toy Safety Regulation (EU) 2025/2509, Art. 19(11), verbatim:
"The manufacturer or the digital product passport service provider shall ensure that a link to the section of the Safety Gate Portal referred to in Article 34(3) of Regulation (EU) 2023/988 for the transmission of information about toys that might present a risk to the health and safety of consumers is displayed when accessing the digital product passport."
Not stored — displayed, at access time. Safety Gate appears nowhere in this repo.
Two things make this more interesting than a link:
⚠️ It binds the passport service provider, not only the manufacturer. The article says "or". That makes it the first obligation in the toy or detergent regime that lands on a hosting role as a functional requirement rather than a legal status — if a node hosts toy passports, the node is a place this duty can be discharged, and arguably has to be.
⚠️ It is a rendering obligation, so it binds the HTML surface specifically. The resolver content-negotiates HTML and JSON. "Displayed when accessing" plainly reaches the HTML view. Whether a JSON consumer must receive the link too is a judgement — including it in both is cheap and removes the question.
The target is the Safety Gate Portal section under Art. 34(3) of Regulation (EU) 2023/988 (GPSR) for consumers transmitting information about products presenting a risk, not the recalls listing. Worth getting right: they are different pages with different purposes.
2. ⬜ The data carrier needs an accompanying statement — detergents Art. 21(4)(e)
Detergents Regulation (EU) 2026/405, Art. 21(4): the data carrier shall be, among other things:
"(e) accompanied by the statement 'Please scan for more comprehensive information on the product' or by a similar statement"
A label obligation rather than a passport obligation, and it lands on the QR render path (/dpp/{dppId}/qr), which currently emits a code and no accompanying text.
"Or by a similar statement" leaves room, and the quoted wording is the safe default. The language question applies here too — a statement aimed at a consumer is owed in the Member State's language.
⚠️ Detergents-specific. Toys Art. 19(7) requires the carrier to be visible before purchase but mandates no wording.
3. ✅ No registration, no password — and it holds by accident
Toys Art. 20(4): "Consumers shall not be requested to register or provide a password to access the digital product passport."
Detergents Art. 22(d): the same, for consumers and other end-users.
Currently satisfied. The resolver's /dpp/{dppId} route carries no authentication layer — only a rate limiter, a trace layer, HTTP metrics and request-id middleware. None of those is a credential, and a rate limit is not a registration.
⚠️ But nothing states the rule and no test asserts it. The guarantee lasts exactly as long as nobody adds an auth layer for a good-sounding reason — abuse mitigation, tenant scoping, a telemetry requirement. Each of those is a plausible future PR, and none of them would trip anything today.
A gate that has never been asserted is not known to hold. One test that pins the public passport route as reachable with no credential turns an accident into a guarantee, and it is the cheapest item in this batch.
Timing
Detergents binds 23 September 2029, toys 1 August 2030. Nothing is due.
Item 3 is worth doing now anyway, because its cost is one test and its value is protecting a property that is currently true and undefended. Items 1 and 2 are backlog until there is a toy or detergent passport to serve.
Filed together because all three bind the same surface, and a single pass over the serving layer is cheaper than three.
Three obligations from the toy and detergent passport regimes bind the surface that serves a passport to a consumer — the resolver and the QR render path — rather than the data model. Two are absent; one holds by accident.
1. ⬜ The Safety Gate link must be displayed on access — toys Art. 19(11)
Toy Safety Regulation (EU) 2025/2509, Art. 19(11), verbatim:
Not stored — displayed, at access time.
Safety Gateappears nowhere in this repo.Two things make this more interesting than a link:
The target is the Safety Gate Portal section under Art. 34(3) of Regulation (EU) 2023/988 (GPSR) for consumers transmitting information about products presenting a risk, not the recalls listing. Worth getting right: they are different pages with different purposes.
2. ⬜ The data carrier needs an accompanying statement — detergents Art. 21(4)(e)
Detergents Regulation (EU) 2026/405, Art. 21(4): the data carrier shall be, among other things:
A label obligation rather than a passport obligation, and it lands on the QR render path (
/dpp/{dppId}/qr), which currently emits a code and no accompanying text."Or by a similar statement" leaves room, and the quoted wording is the safe default. The language question applies here too — a statement aimed at a consumer is owed in the Member State's language.
3. ✅ No registration, no password — and it holds by accident
Toys Art. 20(4): "Consumers shall not be requested to register or provide a password to access the digital product passport."
Detergents Art. 22(d): the same, for consumers and other end-users.
Currently satisfied. The resolver's
/dpp/{dppId}route carries no authentication layer — only a rate limiter, a trace layer, HTTP metrics and request-id middleware. None of those is a credential, and a rate limit is not a registration.A gate that has never been asserted is not known to hold. One test that pins the public passport route as reachable with no credential turns an accident into a guarantee, and it is the cheapest item in this batch.
Timing
Detergents binds 23 September 2029, toys 1 August 2030. Nothing is due.
Item 3 is worth doing now anyway, because its cost is one test and its value is protecting a property that is currently true and undefended. Items 1 and 2 are backlog until there is a toy or detergent passport to serve.
Filed together because all three bind the same surface, and a single pass over the serving layer is cheaper than three.