Milestone 1 Complete: The DPP AI Agent Is Working (And It Was Harder Than It Looks)
Building in Public — DPP Kit
Milestone 1 is done.
That's the headline. All five UNTP credential types are now live in DPP Kit — Digital Product Passports, Digital Facility Records, Digital Traceability Events, Digital Conformity Credentials, and Digital Identity Anchors — and the AI Agent is doing the heavy lifting on DPP and DFR creation.
This is the thing I've been building toward since day one. A user can upload a product spec, a sustainability report, a supplier data sheet — and the AI Agent reads it, maps it to the UNTP schema, and hands back a structured, Tier 2 conformant credential. They review it, accept or reject individual fields, and issue. What used to be a week of manual data wrangling can happen in a sitting.
Getting there was messier than I expected. Here's what actually went into it.
What the AI Agent Does Now
The agent handles two of the most data-heavy credential types: Digital Product Passports and Digital Facility Records. These are the ones where you're pulling product composition data, emissions figures, facility certifications, provenance claims — genuinely complex structured data that's painful to enter manually.
The workflow is document-in, credential-out. Users upload whatever they have — PDFs, Word docs, spreadsheets, CSVs — and the agent extracts and maps the relevant data. There's a review step where users can accept or reject per field, and the whole thing validates against UNTP Tier 2 conformance before anything gets signed and issued.
For Digital Conformity Credentials — the compliance certificates issued by CABs and certification bodies — the platform pulls them in from external UNTP-issuing tools. The DCC is the most technically complex credential type, and supporting it via external issuers was always the right architecture. You don't want to reinvent accredited certification workflows; you want to reference them. DCC's will be the most complex challenge because it requires Standards Organizations to build a Conformity Vocabulary Catalog (CVC - a Data Template) so that other UNTP systems can work interoperability with the data packages. The important thing now is that DPP Kit users can paste the DCC id into DPP Kit and it will be added to DFR's and DPP's. That's a win!
That's Milestone 1: all five types, AI-assisted where it matters most, and external DCC support for the ecosystem approach.
The Bugs That Taught Me Things
I'm not going to pretend this shipped cleanly. There were three bugs in the AI Agent alone that each had a real lesson buried in them.
Stale closure bug. The AI chat was sending outdated credential data to the agent. User makes changes in the editor, asks the agent to help with something, and the agent is working from a version of the credential from ten minutes ago. Classic React closure problem — the event handler captured old state. Fixed by making sure the current credentialSubject is always read fresh before sending to the agent, not captured at render time.
Server-side field overwriting. There's a function called enforceImmutableFields on the server that protects certain credential fields from being changed. Turns out it was also clobbering producedByParty — a field that actually supports three different user-driven input modes: linking to an internal DFR, referencing an external DFR URL, or entering manually. The server was treating it as read-only when it's anything but. Fixed by correctly scoping what "immutable" actually means.
n8n session history poisoning. This one was subtle and annoying. After fixing the frontend stale closure bug, the agent was still sometimes regressing user changes. Why? Because the n8n workflow that runs the agent has conversation memory — and that conversation history still contained the old stale credential data from earlier in the session. The frontend was sending correct data, but the AI was weighting older context and effectively undoing user edits.
The fix was a "ground truth" pattern: every chat message now prepends the current credentialSubject as the authoritative state, and both the DPP and DFR agent prompts have an explicit instruction (Rule 7) telling the AI to always trust the current credential data over anything in conversation history. It's a pattern I'll use going forward — when working with AI in agentic loops, you can't assume conversation memory is your friend. You have to assert truth on every turn.
A Billing Edge Case Worth Noting
Caught a subtle bug in the tier system: new organizations created by paid users were getting trial-tier AI limits instead of inheriting the user's subscription level.
The fix was a "highest tier across user's orgs" resolution logic — when determining AI quota for a new org, the system now looks at the highest tier active across all of a user's organizations and applies that. Also added a per-org ai_call_limit_override field for cases where I need to make a manual adjustment without touching the underlying tier. Flexibility without a full tier change.
DPP Render Template Expanded
The rendered view of a Digital Product Passport is what gets QR-coded and shared downstream. It needed to show more.
Added product image rendering (DFR had this already — DPP was missing it), plus three new sections: an emissions scorecard, a circularity scorecard, and traceability information. All sections handle Directus file links through the /api/assets/ public proxy, so evidence documents stored in S3 render correctly whether you're viewing the credential inside DPP Kit or verifying it externally.
This matters because the rendered credential is often the first thing a buyer or auditor sees. It needs to be readable and complete, not just machine-parseable.
Infrastructure: Caught a Storage Problem Before It Became a Crisis
Noticed the production server had accumulated around 23GB of Docker build cache from repeated CI/CD deployments. Not immediately dangerous, but the kind of thing that eventually causes a 2am incident.
Added automatic post-deploy cache pruning to the GitHub Actions workflow — a rolling 7-day window that clears old build cache after each successful deployment. Small operational hygiene fix, but the kind of thing that's easy to skip when you're moving fast and worth doing before you need to.
Where I'm Thinking About Selective Disclosure
Not shipping yet, but I spent time this sprint designing how encrypted credential views will work — and I expect this to be live by April.
The concept: a "master credential" that contains all data, with multiple field-level view configurations — public, regulator, supplier — each signed and optionally encrypted separately. You get selective disclosure without every downstream system needing access to everything. This is an important feature for real-world deployments, where what a regulator needs to see and what you share publicly are genuinely different things.
The one honest constraint: VCKit doesn't yet support SD-JWT or BBS+ for standards-based selective disclosure. So the path forward is to build the UI and data model first — saved view configs, field selection — and wire it to SD-JWT signing when the standard support lands. The user experience will be identical either way. Only the cryptographic plumbing changes underneath.
That's the plan: ship the full view configuration capability in April with the current signing approach, with SD-JWT as a drop-in upgrade when VCKit supports it. Design for where the standard is going, ship something real for where it is today.
What's Next
Milestone 1 being done means the core capability is proven. Every UNTP credential type, AI-assisted for the ones that need it, with external integration for the ecosystem.
Now the focus shifts to getting this in front of real users. Public launch is March 17 at Vegas Tech Alley. If you're in the Nevada supply chain or tech ecosystem and want to be among the first to try it, grab a free trial at dppkit.io.
The standard is moving fast. The regulatory deadlines are real. And the infrastructure for how supply chains exchange data is being built right now — might as well be part of building it.
DPP Kit is a product of Xylo Digital. Follow along at dppkit.io/blog.