Building in Public

Building in Public: Fixing the UNTP Credential Editor Pipeline

· 5 min read
Building in Public: Fixing the UNTP Credential Editor Pipeline

Building in Public: Fixing the Credential Editor Pipeline

7 commits · 14 files · 319 additions


Tonight's session had one clear theme: the credential editor needed to grow up.

The core flow — upload documents, let the AI agent extract claims, review and edit, issue a credential — was working. But there were enough rough edges in how state moved between the editor, the AI agent, and Directus that real usage was exposing real problems. Ghost claims coming back from the dead. The editor showing you a credential you already signed instead of the draft you're working on. DCC credentials rendering against the wrong schema shape. A dashboard that lied to you with zeros when things went wrong.

Seven commits later, the pipeline is a lot cleaner. Here's what changed.


What's Better Tonight

The Editor Shows the Right Thing

If you issued a credential and then went back to edit it, the editor was showing you the already-signed version — not the working draft. That's backwards. You're trying to edit, and the tool is showing you the final artifact. Fixed. The editor now shows the current Directus draft state, which is where you're actually working.

Related: claim and image deletions made in the AI Agent tab now propagate correctly to the parent editor state. Previously, the two views could drift out of sync. Now they stay in sync through an onCredentialSubjectChange prop that connects them properly.

No More Ghost Claims

This was the most satisfying fix of the night. Deleting a claim should mean it's gone. It wasn't.

Two separate bugs were causing claims to reappear after deletion:

The first was orphaned evidence files. When you delete a claim, the PDF evidence file it was extracted from was staying in Directus. On the next Generate run, the AI would re-read that PDF, re-extract the claim content, and recreate the claim you just deleted. The file is now cleaned up when the claim is removed.

The second was stale array indices. After deleting a claim, the remaining claims kept their old array positions. When the system later tried to reference them by index, it was looking at the wrong positions — leading to out-of-bounds lookups and silent data loss on the next Generate. Index tracking is now recalculated correctly after any deletion.

DCC Credentials Actually Render

The Digital Conformity Credential renderer was reading conformityClaim — but the actual UNTP schema uses assessment[]. The renderer was pointed at a field that doesn't exist in the real schema shape. Rewrote the renderer to match the actual structure.

While I was in the DCC code, I also enriched the metadata the AI agent receives when working with DCCs — assessment details, conformity topics, evidence links. Better context means better credential generation when a DCC is part of the chain.

The Dashboard Tells the Truth

The dashboard was showing zeros when API calls failed. Silent failure. It looked like everything was fine; it just wasn't showing you any data. Now surfaces actual errors so you know something went wrong, rather than thinking you have zero credentials issued.

The Deploy Pipeline Doesn't Nuke Infrastructure

Separated docker compose build and docker compose up in the CI/CD workflow. Previously, a routine app deploy could accidentally trigger a rebuild of infrastructure services — VCKit, Directus, etc. Those don't need to be rebuilt when you're just shipping an app update. Now they're separate steps.


The Technical Pattern Underneath

Most of these fixes are variations on the same problem: distributed state that wasn't being kept in sync.

The credential editor is essentially three things talking to each other — a React frontend, a Directus CMS backend, and an AI agent pipeline. Each has its own view of a credential-in-progress. When they drifted out of sync, you'd get the wrong version showing in the editor, or deletions that didn't fully propagate, or the AI regenerating things you'd already removed.

The fixes tonight were about making those sync points explicit rather than implicit. The onCredentialSubjectChange prop is a small API surface that makes the parent/child relationship between the editor and agent tab a deliberate contract. The evidence file cleanup makes credential deletion a complete operation, not a partial one. The index recalculation makes the data model consistent after any mutation.

The DCC schema fix is simpler — just reading the right field name — but it's a good reminder that schema drift between what you expect and what the spec actually says is a real hazard when implementing a standard that's still evolving.


Where This Fits

DCC credentials are the next major capability unlock. They're more complex than DPPs and DFRs because conformity assessment involves claims, evidence, and third-party accreditation all woven together. Getting the renderer right and getting the AI agent better context for DCCs is foundational work for that.

The editor stability work matters because the editing loop is where practitioners spend most of their time. The AI generates a first draft; the human reviews, edits, and refines; then issues. That loop needs to be trustworthy — you shouldn't have to wonder whether the version on screen is the version you'll sign.


DPP Kit is in active development. If you're working on UNTP implementation and want to follow along or get early access, reach out at dppkit.io.