OpenVTC Verifiable Trust
Workshop

Affinidi · OpenVTC · ToIP DTG Working Group

The Verifiable
Trust Stack

VTI, OpenVTC, Trust Tasks, delegated execution and DTG credentials — what each piece is, and how they compose into something you can actually build on.

Seven acts No prior knowledge assumed Interrupt whenever you like

Before you start: press F for fullscreen, N toggles these notes, / or click left/right half of the screen to move. The URL carries the slide number, so a reload puts you back where you were.

Frame the room. Twenty people, first exposure. Nobody needs to remember crate names. Tell them the only thing to take away is the through-line on slide 8 — one idea and the three things it unlocked. Everything after that is one of those, in more detail.

Colour is a system, say so once: purple = identity and custody; lime = the wire and execution; gold = communities and the graph; orange = things that aren't done. The rail on the left edge changes with the act.

No fixed clock. Every slide stands on its own, so run long where the room is interested and skip where it is not. The three you should never skip: 8 (the through-line), 30 (the delegated-execution flow) and 51 (what is solid and what is not).

I

Act One

You already have
a digital twin.
You just don't own it.

It is scattered across four hundred accounts, and every one of them belongs to somebody else. Now we are handing AI agents the keys to it. That is the problem this stack exists to solve.

Open with the count. Ask the room how many online accounts they think they have. The honest answer is in the hundreds. Every one of them holds a fragment of who they are, and not one of those fragments is theirs.

Then the turn: for twenty years that was merely annoying. It stops being annoying the moment an AI agent acts on your behalf. An agent needs to know who you are, what you are allowed to do, and who vouches for you — and right now the only way to give it that is to hand it every password you own.

The phrase to plant, because the whole deck pays it off: a digital twin you actually own. Not a profile someone keeps about you — a thing that holds your keys, your credentials, your memory and your rules, that you can point at a service, and that can say no on your behalf.

Keep it to two minutes and do not explain the architecture. This act is the argument, not the mechanism.

The one idea

Make the relationship the thing that carries proof.

Nodes

Identifiers you control

Not an account on someone's server — an identifier that resolves to your own public keys, that you hold, and that nobody can delete you out of. Every person, organisation, device and agent in the picture is one.

Edges

Signed statements about a relationship

“I am a member of this community.” “I know this person.” “I vouch for this attribute.” Each one signed by whoever is making the claim, and checkable by anyone who receives it.

Your digital twin is not a profile. It is a graph of relationships you can prove — and the rest of this stack is the consequence of taking that seriously.

  • Portable. The relationship travels with the parties. No platform hosts it, so no platform can end it.
  • Reciprocal. Both sides issue and sign their own credential, so an edge carries two signatures and neither party can invent it alone.
  • Revocable. Withdrawal is a checkable event, not a row quietly deleted.
  • Composable. Edges make a graph, and a graph can be walked, scoped and asked questions.

Two different questions, and both have answers. “Was this claim really made?” is arithmetic — anyone can verify the signature, offline, forever. “Is it still true right now?” is governance — you ask the community's trust registry, live. We build both, and the second one is not an afterthought.

This is the slide people should photograph. Nodes are identifiers you control; edges are signed claims about relationships. Everything in Act VI depends on it.

Do not say "no registry needed" — it is wrong and it undercuts our own architecture. The fragment draws the line that matters: a signature settles authenticity and needs nobody's permission; a trust registry settles current status, and we actively advocate one per community and per network. TRQP is a first-class part of this stack, not a fallback.

"Reciprocal" surprises people — say it explicitly: a relationship here is two credentials, not one. That kills the whole class of "I'll just assert I know them" attacks.

Deliberately no DID methods yet. Identifiers are enough at this altitude; the methods get a proper slide in Act II.

Where this comes from

Self-sovereign identity was right.
The first generation of it did not work.

The original philosophy

SSI

You should hold your own identifiers and credentials, present only what is needed, and depend on no platform to be yourself. Nothing about that premise has aged badly.

What actually happened

Generation one stalled

Wallets nobody installed, issuers with nobody to issue to, ecosystems that needed a government or a consortium to exist first, and interop that lived in slide decks. The technology mostly worked. The bootstrap never did.

What changed

Start from relationships

Not "issue everyone a credential and wait", but people vouching for people, inside communities that govern themselves — which bootstraps from two participants rather than from a national programme.

The source document

The First Person Project
white paper

by Drummond Reed

firstperson.network/white-paper

It names the two things generation one never had: a Verifiable Trust Agent — the digital twin that holds your keys, credentials, memory and rules — and a Verifiable Trust Community, which governs who belongs and vouches for them. First-person trust, personhood scoped to a community, relationships as credentials, a network of networks.

We are building the VTA, the VTC, the operator tooling around them, and an ecosystem on top — personal AI agents through to enterprise fleets. And we are at the very start of it.

Be genuinely honest about generation one. Half the room will have lived through it, and a deck that pretends SSI succeeded loses them in thirty seconds. The failure was not cryptographic — it was that the model required an ecosystem to exist before anyone could use it.

The pivot in one line: generation one asked "who will issue the credentials?" This asks "who do you already know?" A community of two is a working system; a credential nobody issues is not.

Say the credit out loud rather than leaving it on screen. Drummond Reed's First Person Project white paper is where the argument comes from — being clear about which ideas you originated and which you implemented is the fastest way to be trusted on everything else for the next two hours. He is also among the editors of the DTG Core Credentials spec, so the paper and the ToIP standardisation are one lineage.

End on the last line and mean it — "we are at the very start". It sets expectations honestly and it is more exciting than claiming to be finished.

Ninety seconds to two minutes. Never cut this slide.

Receipts

We did not draw this on a whiteboard.

2025-03 — 34 commits 2025-04 — 8 commits 2025-05 — 10 commits 2025-06 — 23 commits 2025-07 — 6 commits 2025-08 — 25 commits 2025-09 — 69 commits 2025-10 — 38 commits 2025-11 — 30 commits 2025-12 — 35 commits 2026-01 — 23 commits 2026-02 — 129 commits 2026-03 — 153 commits 2026-04 — 285 commits 2026-05 — 773 commits 2026-06 — 1079 commits 2026-07 — 857 commits 2026-08 — 758 commits the stack itself starts here February 2026 → 1,079 2025 — the foundations 2026 — heads down commits per month · all 24 repositories
4,335
commits
24
repositories
12,197
tests
6
months for the core of it

A year of quiet foundations. Then February, when we started building the actual thing — and did not really stop.

108 crates. 350 published specifications. A trust graph with eighteen thousand real signed credentials in it. None of this is a mock-up, and none of it is behind a login.

This slide exists to buy you the next two hours. A room being shown an architecture wants to know whether it is real. Show them, then move on — do not narrate the numbers.

The shape is the message: a flat 2025 while we built identifiers, credentials and messaging primitives, then a hockey stick from February when the agent and the community service started. Point at the cliff, say "that is when it stopped being a research project", and go.

If you want one line of swagger, it is the last one: none of it is a mock-up and none of it is behind a login. Everything on the QR wall at the end is public.

Counted from local git history on 2026-08-30. August is a near-complete month. Recount before reusing — the script is in the README.

Community layout · the root fork

A passport, or a letter of introduction.

Both are real trust. They are produced in completely different ways, and a system has to pick.

The passport · hierarchical, state-rooted

eIDAS 2.0 / EUDI

One tree. Trust starts in law and flows down through accredited intermediaries. Nobody asks who you know — they ask who certified the certifier.

Shape
Commission → Member State → provider
Trust data
Published, then fetched — a signed trusted list
Anchors
X.509 roots, state PKI throughout
Membership
Accreditation — a body certifies you
The wallet
Consumes trust. Vouches for nobody.

Buys: legal effect and cross-border recognition.

The introduction · federated, community-rooted

VTI

Many peers. Trust starts in a community's own governance and moves sideways by recognition. It works between two people before it works between two states.

Shape
Community ↔ community, no root
Trust data
Queried live — “is X a member right now?” via a trust registry
Anchors
Identifiers that resolve to keys, no certificate hierarchy
Membership
Governance — the community's own policy decides
The community
Vouches for its members and publishes the roster

Buys: communities without a state, and no accreditation gate.

Neither subsumes the other. A trusted list is authoritative but only as current as its last publication; a live query is current but unaccredited. Hierarchy buys legal effect. Federation buys you a fabric where no government has jurisdiction — which is most of the internet, and all of the agent economy.

Two build-outs. Walk the whole left column first — let the room sit in the passport world, which is the one they know. Then reveal VTI and walk the same five rows in the same order, so the comparison lands row by row. Then the closing fragment.

The parable does real work: a passport is trustworthy because of who issued it; a letter of introduction is trustworthy because of who wrote it and whether they still stand behind it. Both are legitimate. Only one of them scales to communities that no state has heard of.

Accuracy guard — do not soften. Never present VTI's registries as an implementation of trusted lists. They are a different mechanism answering a different question, and the comparison it invites is one VTI loses on the only axis that would then matter: accreditation.

The map · the ToIP four-layer model

The same shape as the internet.

LAYER 4 · TRUST APPLICATIONS many OpenVTC · commit trust · agent memory · MCP bridge LAYER 3 · TRUST TASKS many the task registry · ceremonies · credentials · consent LAYER 2 · TRUST SPANNING ONE — the narrow waist TSP · DIDComm v2 · relays · delivery LAYER 1 · TRUST SUPPORT many DIDs · keys · agent custody · trust registries · witnesses GOVERNANCE ToIP DTGWG Trust Tasks framework DTG creds community policy
The ToIP Technology Architecture model. Every layer holds many alternatives — except layer 2, which holds one. That is the point.

This is not our diagram. It is the Trust Over IP four-layer model, and it is shaped like TCP/IP on purpose: many things below, many things above, one narrow waist in the middle.

IP won because everyone agreed on one thin spanning layer and disagreed about everything else. Layer 2 is that waist for trust — TSP and DIDComm both sit in it, on equal footing — so a Trust Task written once runs over either, and over whatever comes next.

Why the order matters

Identifiers and keys are the bottom, not the point. Applications are the top, and they are consequences. The two middle layers are where interoperability is either won or lost — and they are the two layers this stack contributes most to.

All twenty-four of our repositories live on one of these four rows.

Anchor slide. Come back here whenever anyone loses the thread, including in Q&A. Name the layer you are entering at the start of each act.

The hourglass is the whole argument. TCP/IP has one IP layer and thousands of link layers below and applications above. ToIP copies that shape deliberately: agree narrowly at layer 2, and let layers 1, 3 and 4 be plural. If someone asks "why not just standardise everything" — that is why.

Say explicitly that TSP and DIDComm are both layer-2 citizens here. Anyone who has seen an earlier version of this material will expect DIDComm to be privileged; it is not, and the transport is now chosen per peer from the DID document.

The governance column is dashed because it is not a protocol layer — it runs alongside every layer. If nobody asks, do not explain it.

The through-line

One idea, and three things it unlocked.

The idea

A digital twin that holds your keys, your credentials, your memory and your rules — and can say no on your behalf.

That is the Verifiable Trust Agent. Key material has one home and you decide whether any of it ever leaves — released to your applications and services, on your terms, or never at all.

Not “keys can never move”. Keys move when you say so, to things you own.

What that made possible — each one built on the last

1
Trust Tasks. Every operation has a name, and the name is a published spec — not an endpoint. Protocol-agnostic by construction: the same document runs over TSP, DIDComm or REST.
2
Trust Ceremonies. Because tasks are named and typed, a sequence of them can be specified too — roles, ordering, what counts as done, what evidence it yields. Real work is never one round trip.
3
Delegated Trust-Task Execution. Because an operation is a name a policy can reference and a human can read, an untrusted third party can ask your agent to act — and your agent shows you exactly what would happen, and executes only that.

None of those three were designed in. They fell out of naming the work properly.

The most important slide in Act I. The old version of this slide was four unrelated maxims with act numbers on them; this one is a single idea and a chain of consequences, which is what the deck actually argues.

Correct the "keys never move" instinct out loud. The VTA is not a prison for key material. It is custody with policy: by default nothing leaves and it signs on your behalf, but you can deliberately release material to your own applications and services. The choice is the operator's, and that is the feature.

The ladder is the spine of the next four acts — Trust Tasks (Act IV), ceremonies (also IV), DTTE (Act V). Say the numbers as a progression: name the work → sequence the work → delegate the work safely.

The closing fragment is the honest and the exciting part: this was emergent. Nobody set out to build delegated execution; it became available once operations had stable, published names.

Good place for the first Q&A pause — two minutes, no more.

Three steps into a ladder
we didn't know was there.

End of Act One

Pause here. Say nothing for two seconds. This is the end of the argument and the start of the machinery, and the room needs a breath between them.

The honest version if you want to expand: nobody set out to build delegated execution. It became available once operations had stable published names. That is what a good primitive does — it hands you things you did not design.

II

Act Two

Who holds the keys,
and who holds
the people?

One service holds the keys. The other holds the people. Everything else exists to support one of those two.

Six slides. The one that must land is slide 11 — the agent is not a key store, it is a digital twin with an opinion. Everything else here is furniture.

VTA · Verifiable Trust Agent

You don't post your seal. You send the document.

A notary holds a seal you cannot borrow. You bring them the document; they check who you are and what you are asking, they stamp it, and the seal never leaves the room.

The VTA is that, for everything digital you are. You send it an unsigned payload; it works out which key applies, signs in memory, and hands back the signature. Nothing that can sign has to travel.

And unlike a notary

It also remembers, holds your credentials, enforces your rules, and can refuse — including refusing until a human on another device says yes.

A key management service

  • Stores keys
  • Signs what it is asked to sign
  • Authorises by IAM role
  • Knows nothing about you

A Verifiable Trust Agent

  • Is an identity — it has its own DIDs and can be spoken to
  • Signs under policy, and can require a human
  • Holds credentials, secrets, memory and app state
  • Enrols and revokes the devices and agents that act for you
  • Is reachable over TSP, DIDComm or REST — asleep, behind NAT, anywhere

Every key it will ever hold descends from one recoverable root, deterministically. Your backup is a phrase, not an export.

Lead with the notary and let it breathe. It answers three questions before they are asked: how do I back it up, how do I get keys out, what happens if it is stolen.

Do not go into derivation schemes. The implementation is a standard hierarchical-derivation design; what matters on this slide is the consequence — one recoverable root, deterministic derivation, so recovery is a phrase rather than a key export. If someone wants the BIP-32 path spec it is in docs/04-reference/bip32-paths.md.

The comparison table is the point of the slide. People arrive assuming "VTA" is a rebranded KMS. The five rows on the right are the difference, and four of them have nothing to do with keys.

"It can refuse" is the seed for Act V. Plant it here.

VTA · what it actually holds

Everything a digital twin needs somewhere to live.

Keys & signing

It signs. It never hands the key over. Ed25519, X25519, P-256, and no export button.

Credential store

Issues, holds, presents and revokes your verifiable credentials.

Secrets vault

Secrets sealed to a recipient, with usage recorded. Separate from credentials on purpose.

Agent memory

Your AI assistant's model of you — audited, backed up, and not in somebody's product.

Application state

Versioned storage for the apps you run, where you can see it, back it up and revoke it.

Approval policy

Your rules. Which actions need a human, who may approve, how many must agree.

Consent

Requests, decisions, approver sets, revocation. Human-in-the-loop as a first-class thing.

Devices & agents

Register, wake, disable, wipe. A phone, an extension and an AI agent are the same kind of thing.

Identity & operations

DIDs, agent names, hosting, passkeys, trust contexts, and the plumbing to run it all.

Nine things, one way in. Same named operation, whichever wire it arrived on. No side door, and no secret feature that only the command line can reach.

Do not read the nine boxes. Pick three the room will not expect — agent memory, application state and approval policy — and say why each belongs in a custody root rather than in an app.

The argument for memory and app-state living here: they are the parts of your digital twin that are most revealing and least protected today. They sit behind the same ACL, the same audit trail and the same backup as the keys.

Vault and credential store are separate on purpose, gated on different capabilities. Say that if anyone asks why there are two.

The closing fragment is the structural claim, and it sets up Act IV: one uniform way in, for all nine.

Trust contexts

You are not one identity. Stop storing yourself like one.

YOUR AGENT one seed · one backup personal apple own keys google own keys facebook own keys work eng own keys payroll own keys communities openvtc own keys Apple's context cannot see Google's. Different keys. Different identifiers. Nothing shared. Hand someone this folder and they run everything under it — and nothing else. Eight levels deep, if you want them. All of it from the one seed phrase.
Folders, and sub-folders. Every leaf is a sealed compartment.

You at work, you in a club, you buying a sofa from a stranger. Those should not be able to see each other — and in every system you use today, they can.

A trust context is a sealed compartment inside your agent: its own keys, its own identifiers, its own credentials, its own memory, its own grants. Contexts nest, like folders.

What that actually buys you

  • A blast radius. Lose one context and the others are untouched — the keys were never related.
  • Surgical revocation. Cut an agent out of one compartment without touching your own login.
  • Delegation you can live with. Give someone the work folder. They administer all of it, and nothing above or beside it.
  • No accidental correlation. Different compartments, different identifiers. Nobody joins you up by comparing notes.
  • Still one backup. Every key in every context descends from the same recoverable root.

Open with the three yous. Work, club, stranger. Then the uncomfortable bit: in every system they use today, those three are the same row in the same database, and the only thing stopping them being joined up is a product decision somebody else made.

“Folders” is the whole explanation. Everyone has the intuition already — a folder tree, permissions that inherit downward, nothing leaking sideways. Do not reach for a better metaphor; there isn't one.

The delegation point is the one operators react to. Admin of a parent context administers the entire subtree — create sub-contexts, manage their access, their keys, their data — and has no reach outside it. That is how you hand a team their own corner of your agent without handing them yours.

If asked how the isolation is enforced: the context's identifier is its path, so the authorisation check is a segment comparison on data already inside the verified token — no lookup, nothing that can fail open, and acme deliberately does not match acme-evil. Keys nest the same way, so a sub-context's keys derive underneath its parent's. Eight levels maximum.

Status: this is done on the agent — the model, the nesting, the derivation and the authorisation gate all shipped. The community service never held contexts in the first place; it only references them.

The brands are illustrative. If the room is enterprise, swap them for two customers and a regulator and the point lands harder.

VTC · Verifiable Trust Community

A community that writes its own rules.

Who is in
The roster, the joins, the removals. This is the authoritative answer, and it is the community's, not ours.
Who decides
A policy engine runs their rules. Admission is something a community writes, not a feature we shipped.
What it hands out
Membership, endorsement and relationship credentials — every one revocable in a way outsiders can actually check.
Who else can ask
It publishes the roster to a trust registry, so a peer community can ask “is this person a member right now?” and get a live answer.

And it holds no keys of its own

An agent provisions the community once, at setup, and then gets out of the way. One agent can host many communities.

The community service never runs in secure hardware — it serves a public website, which is the wrong shape for an enclave. The agent behind it does. The hardware boundary sits exactly where the secrets are.

The colour just went gold — we have moved from custody to community. Call it out once and the rail does the rest.

The line that matters: admission is a policy decision the community writes. We supply the evaluator and the inputs. Their rules, their community, their call — that is the entire difference between this and every "join our ecosystem" pitch they have sat through.

The enclave point gets misread constantly. It is not "no secure hardware in this architecture". It is: the community service is not enclaved, and the agent holding its root keys is. One layer down, exactly where the secrets are.

The provisioning handshake used to have its own slide. It does not need one — "provisioned once, then independent" is the whole story, and the detail is in the docs.

The foundation

All of it runs on DIDs.

THE IDENTIFIER did:method:something globally unique nobody assigns it to you resolve THE DOCUMENT PUBLIC KEYS sign · authenticate · encrypt to your own PKI, no certificate authority anywhere SERVICE ENDPOINTS TSPTransport · DIDCommMessaging VTARest · agent names · … how to reach me, and how to talk
Three jobs in one primitive: a name, a key directory, and a way to be reached.

That third box is why the transport question in the next act has an answer. Capability is advertised in the document, not configured per peer.

Methods the Affinidi DID resolver handles

On by default
did:key · did:peer · did:web · did:webvh · did:scid · did:jwk
Opt-in
did:ethr · did:pkh · did:cheqd · did:ebsi · did:webs
Cached by nature
Immutable methods derive their document from the string itself and never expire. Mutable ones are fetched and time out — because a document that can change must be allowed to.

Why a short list

Supporting forty methods badly is worse than supporting six well. We deliberately focus on a small set first to make interoperability real rather than theoretical — and everything past the default set is a feature flag away, not a rewrite.

Two you will meet again: did:key — immutable, zero infrastructure, derived straight from a public key. did:webvh — a portable identifier with a signed, replayable history and key pre-rotation, for anything that has to outlive a domain name.

Three jobs, in this order: a globally unique name nobody had to assign; a public-key directory you publish yourself; and a set of service endpoints that say how to reach you. The third is the one people forget and the one the whole next act depends on.

The analogy that works: a phone number that carries its own directory entry — and its own switchboard address.

The interoperability point is a real position, not modesty. Say it plainly: a short, well-tested method list is a choice. Anyone who needs a chain method can turn one on.

Do not go deep on did:webvh here; it comes back in Act V when a third party edits one. If asked: self-certifying so it survives moving domain, signed history you can replay, and pre-rotation so a stolen current key cannot take the identity over.

III

Act Three

How does any of it
actually reach
anyone?

The least glamorous layer in the stack, and the one that decides whether any of the rest is usable.

Six slides. People arrive assuming transport is a solved detail. It is not — and the two hardest correctness problems in this stack (silent drops, and who learns who you are talking to) both live here.

Frame it as: everything you saw in Act II has to reach someone. Two agents that both want to be reachable is a genuinely hard problem, and every choice in this act is a trade between size, privacy and effort.

Transport

Three doors. One room.

TSP metadata-private DIDComm v2 mediated, async REST synchronous libp2p · next a door, not a rewrite THE SAME TRUST TASK DOCUMENT the payload does not know or care which door it came through one shared operations layer one store · one ACL · one audit trail
Three transports, one authorization path. Adding a fourth adds a door, not a second implementation.

Three ways in, and they are peers. Which one gets used is decided per conversation, from what both parties advertise — not by which one we happened to build first.

Why this matters more than it looks

Two transports with two authorization implementations is how you ship a bypass. Here every door leads to the same operations layer — same access control, same audit envelopes, same task binding. There is no second implementation to drift out of step with the first.

Authentication is the same challenge-and-response shape on all three. On the encrypted transports it goes further: unwrapping the envelope is the proof of who sent it, so no bearer token is ever minted — nothing to steal, nothing to forget to check.

The dotted door is not decoration. Because the payload is transport-agnostic by construction, adding libp2p — or anything else worth adding — is a new implementation of one trait, not a new version of the protocol.

Colour goes lime — we are on the wire now, and stay there for the rest of the act.

Give TSP and DIDComm equal billing, deliberately. Anyone who has seen earlier material will expect DIDComm to be the default; it is not. Preference order is TSP, then DIDComm, then REST, and the choice is per peer.

"One shared operations layer" is a correctness claim, not a diagram. Say it that way.

The libp2p door usually gets one question: no, nothing is committed to it. The point is the cost of adding one — and that cost is low precisely because the Trust Task document never names a transport.

Mediators and relays

A post box, for people who can't be knocked on.

A phone behind carrier NAT. A laptop asleep. An agent in an enclave with no inbound port. Everyone wants to be reachable and nobody can accept a connection.

So both ends connect outward to a box that holds mail for them. Neither party ever has to be dialable, online at the same time, or on a public address.

What it buys

  • Asynchrony — the recipient need not be online, or awake
  • Traversal — outbound from both ends, so NAT and firewalls stop mattering
  • Sender proof, for free — opening the envelope yields a cryptographically authenticated sender
  • Contentless wake — a push wakes a sleeping device without telling anyone what it is for
  • Location cover — your correspondents learn a box, not a network address

Protocol-neutral, on purpose

The published mediator is one dual-protocol node: it speaks TSP and DIDComm, over one access-control keyspace, and bridges between them. Your identifier advertises both against the same box.

TSP calls them relays, DIDComm calls them mediators. Same job: take delivery so the endpoints don't have to.

What the box never gets: the contents. In every routing model on the next two slides, the payload stays end-to-end encrypted to the final recipient. A relay moves sealed boxes; it does not open them. The only question that varies is how much of the address it can read.

One real constraint shaped a lot of code: a mediator permits one connection per identifier. Opening a second for outbound instead of reusing the inbound one caused connection flapping that looked like a network fault — the fix was one listener and one send seam for the whole service.

The post box parable does the whole job. Poste restante, a PO box, a pigeonhole — pick whichever the room will recognise. Nobody needs to be home; nobody publishes their home address.

Sender proof for free is worth slowing down on. In an HTTP world "who sent this" is a token you check separately and can forget to check. Here you cannot read the message without learning who sent it.

Say relay and mediator are the same role under two protocol vocabularies. Then nobody spends the next slide wondering whether TSP has one.

If asked "isn't that a central point of failure?" — it is a point of availability failure, never of confidentiality failure. You can run your own, and you can use several. That distinction is the whole answer.

Encapsulation

What is actually on the wire.

TRANSPORT FRAME — websocket / HTTPS the network sees this ROUTING ENVELOPE — encrypted to the relay “deliver this to …” the relay sees this SEALED TO THE RECIPIENT — authcrypt / HPKE proves who sent it · hides it from everyone else THE TRUST TASK DOCUMENT type = https://trusttasks.org/spec/… payload = { … } only the recipient sees this
Each layer is opened by exactly one party. Peel one and you learn only where it goes next.

Envelopes inside envelopes — the same idea as a letter in a courier's bag, except each layer is cryptographically sealed rather than merely folded.

Innermost
The Trust Task document — a named operation and its payload. Identical whichever transport carries it.
Sealed layer
Encrypted to the recipient's keys, and authenticated so opening it proves who sent it.
Routing layer
Addressed to the relay. Says where next, and nothing about what.
Frame
Whatever the wire needs. Replaceable without touching anything above it.

This is why Trust Tasks can sit on top of anything. The document is the constant; every layer around it is negotiable.

Draw it with your hands. Four nested boxes, opened by four different parties, and only the innermost one contains meaning. Once the room has this picture, the next slide costs nothing to explain.

The one thing to emphasise: the sealed layer both hides and authenticates. Two properties, one operation — which is why there is no separate signature to verify and no token to steal.

TSP and DIDComm build these layers differently — that difference is exactly what the next-but-one slide is about — but the shape is the same in both, and so is the innermost box.

Multi-hop routing

Alice and Bob, hiding behind the post.

LAZY — WHAT RUNS TODAY A Alice B Bob R1 R2 R3 “for Bob” “for Bob” “for Bob” One envelope. Constant size at any depth. Every relay learns Alice is talking to Bob. Content stays sealed throughout — only the address leaks.
The sender knows nothing about the path; the relays work it out.
NESTED — EACH RELAY SEES ONE HOP A Alice B Bob R1 R2 R3 “→ R2” “→ R3” “→ Bob” No relay knows both ends. But the line thins because the message shrinks — it left Alice enormous. In DIDComm, ×1.6–1.8 per hop.
The sender builds the whole path up front; each relay peels one layer.
10 hops, 100 KB
Lazy: ~constant, 200–250 KB · Nested in DIDComm: ≈1.7¹⁰ → tens of megabytes leaving Alice

Getting it to your own relay is enough for a trusted mesh — the chain works the rest out, and loop detection is built in. The price is the one in orange: your relays know who you talk to. That is the problem the next slide solves.

Run it as a story. Alice wants to reach Bob without either of them publishing an address. Left: she writes “for Bob” on one envelope and every post office along the way reads it. Right: she nests envelopes so each office sees only the next one — but the parcel she has to carry to the first office is enormous.

The thinning lines on the right are load-bearing — the message shrinks as layers are peeled, which means the worst point is the sender. Point at them.

The blow-up is an encoding artifact, not a law of routing. That framing is what makes the next slide's answer possible, so plant it here.

Do not overstate it: at one or two hops the onion overhead is only ~1.8–3×. It only bites past a few hops. And only the lazy path is implemented today.

DIDComm vs TSP

Have the privacy. Skip the bill.

DIDComm
Every envelope re-encodes everything inside it. Wrap it ten times and the message is hundreds of times bigger.
TSP
Layers concatenate instead of re-encoding. Ten hops of a 100 KB message is still about 100 KB.

Same privacy as onion routing. None of the thing that made onion routing impractical.

Which one gets used is read from both parties' identifier documents — highest preference they both speak, per conversation. No configuration, no guessing, and no silent downgrade. If they share nothing, that is an error, not a fallback.

Let me be straight about this one. What we run today already keeps message size flat. What TSP uniquely adds is that the relays stop learning who you talk to. It is a privacy upgrade, not a speed fix — and the spec is still an experimental draft on a 0.x library. We build on it anyway, on purpose, with our eyes open.

Underneath both

A relay is an at-least-once bus with silent gaps, and six of our own services each invented their own way of being wrong about that — including sends that cheerfully returned success for messages never transmitted.

A send now only says “sent” when it actually sent. Written once, underneath every transport, so nobody has to be clever about it again.

Do not sell TSP as a performance win. The guard is on the slide because it is easy to overstate: the honest claim is metadata privacy at bounded size. We deferred TSP once for exactly this reason, and reversed it when the mediator gained TSP routing and bridging — not because anything got faster.

"A send that lies is worse than a send that fails" is the transferable lesson in the room. Everyone who has wrapped a queue in a synchronous-looking client has shipped that bug.

Status: the delivery layer is built and live-validated against a real mediator; cutting every service over to it is in progress. Say "built and validated, being cut over".

Two slides used to live here — a routing-rules list and an operator-surface tour. Neither survived the "would a first-timer care?" test.

IV

Act Four

How do two strangers
agree on what
the work even is?

The layer that turns “our API” into something two organisations who have never met can build against separately and still have work.

Five slides. This act is where sceptical engineers either buy in or don't — it looks like bureaucracy until you show what it buys in Act IV.

The problem

Every integration re-invents the wire.

Two parties interoperate when they agree on the shape of the work they cooperate on. Today that agreement is scattered:

Where the contract lives

An OpenAPI file, a Confluence page, a Slack thread, and four client implementations that each interpreted it slightly differently.

What breaks it

Change the transport and you rewrite the contract. Move from HTTP to a queue and none of the agreement survives the move.

What you can't do

Point at it. You cannot write a policy, an audit record or a consent prompt that names "the operation being requested", because it has no name.

What if the unit of agreement were not the endpoint, but the outcome?

The third card is the one that matters and the one people skip. Everything in Act IV depends on operations having names you can put in a policy and in a consent prompt. Plant that here so the payoff lands later.

If the room is API-heavy, acknowledge OpenAPI honestly: it describes an HTTP surface very well. It just isn't a description of the work, and it doesn't travel off HTTP.

The Type URI

The name is the contract.

// every operation, on every transport
https://trusttasks.org/spec/{what}/{version}

https://trusttasks.org/spec/acl/grant/0.1
https://trusttasks.org/spec/consent/decision/1.0
https://trusttasks.org/spec/vtc/join-requests/submit/0.1

“Which version of the API is this?” stops being a question. The message says.

What that name buys

  • It travels. Same document over TSP, DIDComm or REST. The carrier is somebody else's problem.
  • It is self-contained. Parties, criteria, schema, identifiers — all in the document. You can verify one on paper.
  • It is checkable. One JSON object against a published schema, and on REST the header is exact-matched at start-up — so a handler and its spec cannot quietly disagree.
  • You can point at it. In a policy. In an audit log. In a consent prompt a human reads.

That last one looks like the boring one. It is the one the whole next act is built on.

Land the fourth bullet. Everything in Act V exists because operations have stable, published names that a policy engine and a human can both read. Plant it here and the payoff lands later without a recap.

Exact-match at start-up is the detail engineers respect: the service refuses to boot if a handler and its spec disagree.

"You can verify one on paper" gets a laugh and it is a real claim — the document is meaningful with no network, which is why it can be signed, archived and audited.

The registry, today

It is not a proposal any more.

350
published spec versions in the registry
31
namespaces
5
transport bindings
837
task-URI references in the VTI codebase alone

Largest namespaces

vtc · 75vta · 68 did-management · 34auth · 24 messaging · 21vault · 20 policy · 11device · 11 registry · 10keys · 9 credential-exchange · 8consent · 7

And we ate it ourselves

VTI used to publish its own vendor namespace. All 66 of those task versions are now marked retired, superseded by specs in the shared public registry.

Anyone can publish a registry. Migrating your own production system onto it and deprecating your own namespace is the part that costs something.

Counts were taken from the working tree the day this deck was written and they move weekly. Recount before reusing: find specs -name spec.md | wc -l in dtgwg-trust-tasks-tf. For context on velocity: in mid-June the registry held 126 task-versions.

The retirement story is the credibility half of this slide. Lead with it if the room looks unimpressed by counts.

Governance, licensing and the maturity ladder are deliberately not on this slide — that work is genuinely in progress and putting it up invites a conversation the material cannot yet finish. If asked: it is an open ToIP working group, specs are versioned in public, and the process is being firmed up.

Trust Ceremonies

Real work is never one round trip.

APPLICANT COMMUNITY ADMINISTRATOR discover apply supplement reciprocate acknowledge ask decide solicit dashed = optional · lime = opens the clock · gold = terminal
ceremonies/vtc/member-onboarding/0.1 — the real published definition.

A wedding is not one sentence. It is a sequence with roles, an order, a moment it becomes binding, and a certificate at the end. So is joining a community.

A ceremony definition says all of that, machine-checkably — so an implementation can be tested against the flow, not just each message.

roles
applicant · community · administrator — and which identifier kinds each may use
steps
each one a Trust Task, with who sends it, to whom, and what must have happened first
completion
apply and decide — a refused applicant still produces a complete, verifiable enactment
evidence
what the enactment yields, and who records it
bounds
a 30-day clock, bounded retries, declared privacy exposure and side-effect level

Published at trusttasks.org/ceremony/…, structurally separate from /spec/no message's type ever resolves to a ceremony.

The wedding analogy carries the whole slide. Roles, order, the moment it becomes binding, and the certificate. Everyone has the intuition already.

Walk the diagram in three beats: the applicant applies (lime, it opens the clock); the administrator decides (gold, terminal — a rejection is a complete ceremony, which surprises people and is the right design); then the reciprocal half closes the two-way membership edge, because a membership is two credentials.

Dashed steps are optional. discover can be skipped by an applicant who already knows the criteria, and the enactment is still complete without it — that is what "prev-less and optional" buys.

Honest note if pressed: the definition itself flags a gap — the registry has no task by which an applicant supplies further evidence, so "deferred" is currently a reachable state with no defined exit. It is written into the published ceremony rather than hidden. That is the process working.

V

Act Five

What if a stranger's
website could act on
my most sensitive data —
without ever getting my keys?

One mechanism for “something I do not trust wants my agent to do something” — correct by construction, rather than correct because somebody reviewed it carefully.

Nine slides — the mechanism, then a real hosted identity as the worked example. The densest act and by far the most interesting one. Slide 30 (the flow) is the anchor.

Read the question on the slide aloud and then pause. Everyone in the room has typed a password into a third-party site to let it do something on their behalf. This act is the answer to why they should never have to again.

Status guard for the whole act: DTTE itself is a proposed architectural pillar — the pieces exist across the agent, the SDK, the browser plugin and the mobile agent, and it is being landed, not finished. The hosted-identity example on slides 34 and 35 is real and running. Do not blur the two.

The setup

A website wants your agent to do something.

A page you did not write — a hosting control panel, a bank, any app — needs an action only your agent can perform, because only your agent holds the keys. Publish a change to your identity. Sign a credential. Release a secret.

How everyone does it today

Give the site the power, then hope

  • Hand it a password, an API key or an OAuth token
  • It can now do everything that token can do, whenever it likes, for as long as the token lives
  • You approved access. You never approved an action
  • If the page is compromised, so are you — and you will find out afterwards

What we want instead

The site can only ask

  • It proposes one named action with one payload. That is its entire power
  • Your agent works out what would actually happen, and shows you
  • You approve that exact action, once, on a different device
  • Your agent re-checks everything and executes only what you approved

The shift in one line: from granting access, to authorising an act. A token is a standing invitation. A consent decision is a receipt for one thing.

The old version of this slide described our own codebase's plumbing and meant nothing to a newcomer. This one compares what everyone in the room already does — OAuth, API keys, passwords — with what we want instead. Stay on that ground.

The sharpest way to say it: OAuth asks "may this app act as you?" This asks "may this app do this one specific thing, right now?" Those are completely different questions and only one of them is answerable honestly.

If someone raises scoped tokens or short-lived credentials: they narrow the standing invitation, they do not remove it. Nothing in that world shows the human what will actually change before it changes.

The invariant

One sentence the whole design defends.

Nothing changes unless a real person, on a device we still trust, approved this exact thing — and it is still allowed at the moment we do it.

That is the whole design in one sentence. The formal version has more clauses and no more meaning; it lives in the notes and in the design document, where it belongs.

Four things fall straight out of it

  • The relying party cannot authorize anything.
  • A compromised device cannot self-approve a destructive task if policy names an approver set that excludes it.
  • A compromised device cannot swap the payload after approval — the digest binding fails.
  • Revoking a device stops approvals already in flight from it.

Read it aloud, slowly, and then stop talking. It is deliberately one sentence, and every mechanism on the following slides exists to make one clause of it true.

The formal version, if anyone wants it: no state-mutating Trust Task executes unless the agent has verified a single-use consent decision, signed by a currently-enrolled approver device, whose payload digest equals the digest of the exact payload about to execute, against the exact prior state used to compute the effects the human was shown — and unless policy and device enrolment still permit it at the moment of execution. Every one of those bold phrases is a separate attack it closes.

Then walk the corollaries and name which clause each comes from. That turns a wall of text into a structure.

If you only have time for one slide of this act, it is this one.

The flow · anchor slide

Propose. Decide. Execute.

UNTRUSTED WEBSITE YOUR DEVICE YOUR AGENT — the only trusted part YOUR PHONE “please change my identity” a name + a payload. That is all it may do. relays it adds who is asking, read from the caller — never from the message WORK OUT WHAT WOULD ACTUALLY HAPPEN check the shape · check the rules load the current state rehearse the real handler → the true diff ASK A HUMAN “this will add X and rotate your key” fingerprint 7F2A agent-signed. The site wrote none of this. you match 7F2A BEFORE DOING ANYTHING, CHECK AGAIN is this signed by an approver we still trust? is the payload byte-identical to the one shown? has the state moved? has the rule changed? then, and only then — execute. Once. result — and nothing else
The website's entire power is the arrow on the far left. Everything that matters happens inside the purple box, twice.

The rehearsal is the part a website can never be allowed to do. Checking again at the moment of execution is the part everyone forgets.

This is the anchor for the whole act. Come back here whenever anyone loses the thread, including in Q&A. If you are short on time, keep this slide and skip 31 and 33.

It builds in three clicks — one per word in the title. Propose, decide, execute. Do not click ahead: the empty lanes at the start are doing work.

Walk it in exactly three beats, left to right: the site can only ask · the agent works out the truth and shows a human · the agent re-checks and does exactly that, once.

Point at the far-left arrow and say: that is the entire attack surface the website has. One name, one payload, no ability to write anything a human reads.

"Read from the caller, never from the message" — the page cannot claim to be a different origin, because the device knows who called it.

The thirteen numbered protocol steps behind this picture are in the design note; nobody in a first-exposure room needs them, and the old version of this slide that showed them as ASCII did not render reliably.

Zero trust, taken literally

Only the code about to run knows what it will do.

Your agent believes nothing it is told. Not the website. Not the browser. Not even the public registry describing the operation.

It trusts exactly one thing: the code it is about to execute. So it runs that code as a rehearsal, against the real current state, and reports what came out. The website contributes not one word that a human reads while deciding.

Why this is not paranoia

You ask to add one line to your identity document. A naive preview shows you one added line.

What actually happens: the line is added, your keys are rotated, and two future commitments are refreshed. Nothing in the request asked for that — it lives in the handler's behaviour, not the request's shape.

You would have signed it believing you added a line. Every signature would still verify.

The rule

The list of effects must come from rehearsing the real handler — never from a second implementation that describes it. Second implementations drift, and when they drift the human is confidently misinformed while every signature still verifies.

That is worse than no consent at all, because it manufactures evidence of informed approval.

And for anything destructive

You do not tap “approve”. The page and your phone each show four characters, and you match them.

Every other check assumes your browser is honest. This is the only one that survives it being compromised — because it moves the comparison into your head, across two screens that would both have to be lying in the same way.

It is the ceremony a hardware wallet uses, and a tap-to-approve button throws it away completely.

The strongest slide in the deck. Give it room.

Zero trust is the frame for the whole act — the agent assumes the website is hostile, the browser is hostile and the registry is compromised, and still reaches a correct answer. Every mechanism here is one of those assumptions made concrete.

The key-rotation example is real and it lands every time. Say it slowly: the request said "add a line" and the truthful answer includes rotating your keys.

Do not let anyone soften the four-character match into a tap. A tap proves the device was present, which is exactly the thing you assumed was compromised. It is also why approval must be able to go to a different device than the one asking.

Two slides folded in here: the five-check list and the argument about where "is this destructive?" comes from. If someone pushes on the registry question, the answer is one sentence — the registry describes, the compiled-in code decides, and unknown versions fail closed.

Show the exact plan.
Get that plan approved.
Then refuse to run anything else.

The whole of Act Five

This is the sentence to leave the room with if they remember nothing else about delegated execution. Three clauses, and the third is the one everybody forgets.

It used to be a footnote on the previous slide. It earns its own screen.

Two things the first draft got wrong

The gap between checking and doing.

Time of check to time of use

Nothing re-checked the authorization

Policy is evaluated when the consent request is minted. The task executes after a human has looked at it — minutes later. In between, nothing re-checked anything.

So device/disable and device/wipe did not stop an approval already in flight from the revoked device, and a policy tightened during the window was never applied.

Fix: re-evaluate the policy decision and the approver's enrolment at execution time, not only at mint time. The state pin already did this for the data; nothing did it for the authorization.

Privacy

The digest was a correlator

multihash(JCS(payload)) over a low-entropy payload is a confirmation oracle. “Deactivate did:webvh:abc…” has essentially one serialization — anyone who sees a digest can guess the operation and hash it to check.

And the digest travels through the mediator twice: in the request and in the decision. Authcrypt hides it today — but a compromised, subpoenaed or retrospectively-decrypted mediator turns it into a record of what you did.

Fix: salt it with the per-request challenge, which is why check 1 says ‖ challenge.

Tone goes ember — this slide is about being wrong, and it should look different.

Both of these were found by reviewing the design, not by an incident. Say that: it is the argument for writing the invariant down as one sentence in the first place — you can audit a sentence.

The privacy one generalises well beyond this system: a hash of a low-entropy input is not a blinding, it is an index. That is a lesson people take back to their own work.

Q&A pause here — end of Act V, ~4 minutes. This is where the sharpest questions come.

Made concrete · hosted identity

Edit your identity from a browser that holds none of the keys.

Your identity lives in a signed log somebody has to host. Changing it means signing. So “edit my identity from a website” has only ever had three answers.

Answer one

Put the key in the browser

Your signing key now lives in the most hostile runtime you own. Sleep well.

Answer two

Give the key to the host

You do not control your identity any more. Your host does.

Answer three

Move the authorisation, not the key

The website proposes. Your agent decides. Your phone approves. Nothing that can sign ever moves.

# the whole configuration. yours, not ours.
[policy.approver_sets]
operators = ["did:key:z6Mk…"]   ← named ahead of time

[[policy.require_consent]]
task_type    = "…/webvh/dids/update/1.0"
approver_set = "operators"
exclude_requester = true          ← forces two devices

You wrote these rules. We didn't. Which actions need a human, who may approve them, how many must agree — decided per action, by you.

exclude_requester is the line doing the work: the thing that asks can never be the thing that agrees.

And the host? Witnesses co-sign its updates, watchers mirror the log so it cannot quietly vanish, and it can be run by someone you have never met. The design assumes you would rather not trust it — so it does not.

The three answers are the whole pitch. Say them slowly. Almost every wallet and hosting product in the market is answer one or answer two, and the room will recognise both immediately.

"Sleep well" is a joke — land it dry and move on.

Pre-flight if you ever demo this live: two settings fail silently in opposite directions. Enforcement is off by default with a permissive baseline, so the update just succeeds and looks like it worked; approver sets are empty by default, so a rule naming an unknown set can never be satisfied and looks like a hang. Rehearse the full loop. And the requesting and approving identities must genuinely differ.

The hosting service — server, witness, watcher, control plane — used to have its own slide. The last paragraph is all a first-timer needs; the architecture is in the repo.

What that actually proved

The strongest evidence was the code we didn't write.

The hosting service needed no changes at all

It verifies the proof chain exactly as it always did. It trusts the mathematics, not the caller. Nothing was added to make this secure — something stopped being violated. The trust boundary was already in the right place.

And it generalised immediately

An agent nameexample.com/@alice — is just a line in the DID document. So claiming one is a DID edit, which means it is the ceremony you already have. One mechanism, every action; there was no second thing to build.

The part before the name is a domain somebody controls, so “who vouches for this name?” always has an answer — exactly like an email address, and for the same reason.

Two-sided binding

The website says the name points at this identity. The identity's own record must independently claim the name back. If they disagree, resolution fails — there is no permissive mode.

DNS for identities, with the one thing DNS never asks for: the destination has to confirm it answers to the name.

The plan that wasn't pure. Update keys derive from a counter — and deriving allocates. A naive preview would have shown you one key and installed a different one, with every signature still verifying. The function's own doc comment claimed it was pure. It wasn't.

That is the failure mode from the dry-run slide, found in our own code rather than argued about in the abstract.

Lead with the unchanged host. "We integrated a security model into a third-party service and that service needed no changes" is the single most persuasive sentence available about this design, and it is true.

Accuracy guards — do not soften. Dedicated agent-name/set and agent-name/remove Trust Tasks exist, but only the document-update handler has a dry-run, so the explicit verb shows a match code with no itemised effects. Demo the document edit; mention the verb.

Agent-name resolution cost: the one-round-trip path is the WebSocket resolver and is off by default; a cold miss over plain HTTP is one to five hops. Say "usually one hop", never "always".

The impure-plan bug is the best possible closing note for the act: the dry-run principle is not theoretical hygiene, it caught a real, silent, fully-signed lie.

VI

Act Six

What is a trust graph
actually made of?

What the edges actually are — and what eight thousand of them look like when you build them for real.

Four slides. Lighter than Act IV on purpose — people need the recovery. If you're behind, keep 37 and 39 and cut the rest.

The model

Nodes are DIDs. Edges are credentials.

Nodes — each one a real DID

  • VTN — Verifiable Trust Network: a network of communities
  • VTC — Verifiable Trust Community: a community of members
  • Person · Device · VTA — singleton members

Edges — each one a signed W3C VC 2.0

VMC
Membership. VTN→VTC, VTC→member. Containment.
VRC
Relationship. VTN↔VTN, VTC↔VTC, member↔member. Lateral.

A community is a member of a network exactly as a person is a member of a community — so the whole containment hierarchy is expressed with VMCs, and everything sideways is a VRC.

Reciprocity

Every relationship and every membership is mutual: both parties issue and sign their own credential. A community↔community link is two VRCs. A membership is two VMCs.

So each edge in the graph is backed by two signatures, and every node's credential list labels each one OUTBOUND (issued by this node) or INBOUND (issued to it).

The VMC-vs-VRC distinction is the thing to land: membership is vertical, relationship is lateral. Once someone has that, they can read any part of the graph without help.

Reciprocity is the second callback to slide 3. Say it out loud — a claimed relationship with only one signature is not an edge, it's an assertion.

Note the VTN tier exists but is the least exercised part of the model. Don't oversell networks-of-networks; the community tier is where the running code is.

The family

Seven kinds of signed statement.

VMC
Membership — you belong to this
VRC
Relationship — we know each other
VIC
Invitation — you may join
VPC
Persona — this is a face I chose to show
VEC
Endorsement — I vouch for this attribute
VWC
Witness — I saw this happen
VDC
Delegation — this one may act in my name · proposed

All seven inherit from one abstract DTG credential type, and all seven are ordinary W3C Verifiable Credentials. Community-issued ones carry a status-list index, so revocation is observable rather than silent.

The seventh · in the spec pipeline now

A letter of authority

Everything else says what you are. A delegation credential says somebody may act in your name, for a bounded scope, revocably — the thing an AI agent needs before it can negotiate on your behalf.

  • Single-hop, always. A delegate who needs a sub-delegate asks you; you issue a fresh one directly. You always hold the complete register of who may act as you.
  • Countersigned. The appointment is not valid until the delegate accepts it.
  • Short-lived, and revocation is simply not renewing. No status lookup, so nobody learns when your authority was checked.
  • Six fields, five local checks, no network calls.

Why so austere: a chained delegation has to be verified by resolving its whole ancestry — which discloses the principal, and lets three sub-agents look like three people. The simple version is the private one.

Read the plain-English column, not the acronyms. Seven sentences is the whole taxonomy and it is far more memorable than the class names.

The VDC is the one to spend time on, because it is where the AI-agent story becomes a credential rather than a config file. Frame it as the letter of authority from the guild example: a stranger can check it, and the guild can tear it up.

Status guard: the VDC is proposed — it is in a spec pull request and not yet in the published catalogue, so nothing downstream can claim conformance to it yet. Our own design note argues the draft should be cut down hard for privacy reasons. Say "in the pipeline, and we are arguing about it in public".

The single-hop argument is genuinely interesting and worth thirty seconds: chaining is the thing people reach for, and it is the case where chaining is worst — you cannot revoke what you cannot enumerate.

Also mention taskContext if there is time: a credential can name the exchange that produced it, but context is not outcome — knowing which conversation made a credential says nothing about whether that conversation succeeded.

At scale

You cannot reason about a graph you have never seen full.

The DTG Explorer showing six coloured federations of communities, each a dense cluster of member nodes, joined by gold network-recognition edges.
The DTG Explorer — every node a real identifier, every edge a real signed credential.

Nothing here is mocked. Every node is a real identifier and every edge is a real, signed W3C credential, generated by the same library that runs in production and rendered as a self-contained site with no server.

  • Skewed community sizes — mostly small villages, a few metropolises, so the graph has genuinely different shapes in it
  • No orphans — the community-to-community graph is one connected component, and the “trace path” tool proves it live
  • Cross-community people — a small share of each community's members hold a relationship into a neighbouring one
  • Click any edge and you get the full signed credential, proof and all

Path length, recognition depth, revocation blast radius, query cost — all of it is invisible until eight thousand nodes are in front of you.

If a laptop is on the projector, open the real thing instead of talking about it. dtg-demo./build.sh → open the generated page, then trace a path between two random communities. It lands harder than any slide.

Generation is deterministic, so the same seed gives the same graph — you can rehearse the exact demo you will give. It signs the whole set in seconds.

Guard: this is a generated exemplar, not a production network. The credentials are real; the people are not. Say that plainly so nobody quotes the entity count back at you as users. The counts in the panel come from this particular run — the generator is configurable, so do not treat them as fixed numbers.

VII

Act Seven

What can you
build on it today?

A community you can actually join, a problem you already have solved by accident, and what happens when an AI agent gets a digital twin of its own.

Eight slides, then the demo. This act is the "so what" — everything before it was mechanism. The last three are the VTA as the substrate an AI agent runs against.

The variety this has to support

Three communities. One rulebook.

Communities differ on one axis that changes everything: how much correlation they want. The same machinery has to serve all three.

scope · public

The workshop with the open door

Every tool on the wall has a name scratched into the handle by whoever brought it. Glenn lends his chisel to Linus and everyone sees Glenn's chisel in Linus's hand — that is the point.

The workshop's whole value is that any tool traces back, in public and forever, to the person who vouched for it. Correlation here is the feature.

scope · pairwise

The house where nobody uses names

Every visitor is handed a fresh mask at the door — and a different one for each room. Two people in a room know each other by that room's masks and nothing else.

Walk into another room and you are, verifiably, somebody who belongs in this house — and nothing more. Even the housekeeper is not supposed to know who spoke to whom.

scope · community

The trade guild in between

Most real communities are the guild. Its name is on a public door. Who works there is semi-public. Who each member trades with is nobody's business.

Sofia's employer is public. Her guild membership is community — visible in the hall, not outside it. Her dealings with a supplier are pairwise. And to negotiate for the guild she needs a letter of authority a stranger can check and the guild can tear up.

One person, three scopes, at the same time. That is why identifier scope is a per-community, per-relationship declaration rather than one global rule — and why the delegation credential exists.

Tell all three as stories — the workshop, the house, the guild. They are memorable, they are genuinely different, and they kill the assumption that privacy always means anonymity. The workshop wants to be correlatable.

Land the guild hardest, because most real communities are it, and because Sofia is the argument for scope-per-relationship. One person carrying three different correlation postures simultaneously is not an edge case.

Sofia's letter of authority is the VDC from the previous slide. Point back at it explicitly — it is the same object.

This is the fourth of the deck's community layouts. If someone asks which one we recommend: none. The system's job is to let a community declare its posture and then hold it.

Community layout · the join ceremony

Invitation → verify → admit → membership.

Requesting side

OpenVTC

The applicant's CLI/TUI. Holds their Persona DID, assembles the evidence presentation, speaks DIDComm.

Deciding & issuing side

VTC

Verifies the presentation, evaluates its own policy, mints and delivers credentials, owns the member ACL.

Root of trust · one-time

VTA

Minted the VTC's signing identity at provision time. Not in the per-join hot path.

1
Discover. OpenVTC asks the VTC for its join manifest — the evidence criteria, and the community DID to address.
2
Submit. The applicant builds a Verifiable Presentation, embedding an invitation credential if they were invited, and submits it over DIDComm — where authcrypt already authenticates the sender.
3
Verify & decide. Signatures, holder binding, invitation validity and freshness — then join.rego, the community's own policy. A valid, unconsumed invitation auto-admits with no human in the loop.
4
Issue. Mint a membership credential plus a role endorsement, signed with a key derived from the VTA root, seal them to the applicant's DID, and publish the membership to the trust registry.

Then recognition: a peer community queries TRQP — “is this DID a member right now?” — and mints a cross-community session on the answer. That is federation actually happening, and it is one question over the wire.

Every layer of the stack shows up in these four steps. Call them out as you go: Trust Tasks carry the messages, the VP is DTG credentials, the policy is the community's governance, the registry is the federation.

Step 3's auto-admit is the useful nuance: an invitation is not a shortcut past policy, it is an input to policy. The community can still refuse.

Multi-community membership is supported — one persona can belong to many VTCs at once.

Community layout · a real one

OpenVTC: know your developer.

A tool a developer runs locally, implementing first-person trust — you know who you are dealing with because someone who knows them vouched, not because a platform said so.

public
A stable identifier you are happy to be known by everywhere. Your name on the workshop wall.
community
An identifier that works inside a community and means nothing outside it. Your face in the guild hall.
pairwise
A fresh identifier for every single counterparty, even inside one community. The mask per room — and the default we ship.

Two credentials do the work: a personhood credential, where an ecosystem attests the holder is a real, unique person within that ecosystem — and a relationship credential, issued peer-to-peer between personhood holders, reciprocally.

Why pairwise is the default

If every counterparty sees the same identifier, your relationship graph is public whether you meant it to be or not — anyone who compares notes can reassemble it.

One identifier per relationship turns thirty relationships into thirty fragments that share no vertex. Reuse one, and all of them collapse into a single star pointing at you.

Several yous

Profiles let one person hold entirely separate identities — work, open source, a pseudonym — with no shared state between them.

Scoped personhood is precise, deliberately: “a real, unique person within that ecosystem”. Not a global uniqueness claim, and not a government identity.

Use the scope words, not the old acronyms. Public, community, pairwise — the same three from the previous slide, now as the thing a developer actually configures. Anyone who has read older material will know them as persona and relationship DIDs; the scope vocabulary is clearer and it is what the specs use.

The collapse point is the one to land: thirty relationships under thirty identifiers are thirty disconnected fragments. Reuse a single identifier across them and they become one five-armed star with you at the centre. It is not traffic analysis — it is a lookup.

Scoped personhood: people hear "proof of personhood" and assume both global uniqueness and a government identity. It is neither. Be precise.

The payoff

Commit trust, with nothing in the repo.

your agent holds the key nothing on disk signs the commit names its signer on its own header the PR check every commit in the range no signing stack, no toolchain 1 · resolve the signer does that identifier publish this key? 2 · ask the registry community registry “may this signer commit to this repo, right now?” one grant · covers every repo trusted · exempt → pass anything else → fail, closed
Two identifiers on the command line. Nothing committed to the repository.

Who may sign is a registry grant, not a file in the repo. Enrolling a contributor is one grant, and it covers every repository that grant's resource covers.

Each commit names its signer on its own header. That identifier must publish the key that signed, and the community's registry must currently authorise it for this repository. Three independent checks, and it fails closed at every layer.

The line that lands

Revoking a contributor is one registry operation — not a sweep of every repository's allowed-signers file. Anyone who has run that sweep will feel it.

There is no registry URL to configure either: the endpoint is discovered from the registry's own identifier document, taking the highest-preference transport both sides support — TSP, then DIDComm, then HTTPS.

End the applied section on this because it is not an identity product. It is supply-chain integrity, delivered by everything in the previous six acts, and it solves a problem the room already has.

Walk the diagram anticlockwise: agent signs → commit carries the signer → the check resolves it → the check asks the community. Two identifiers on a command line, and nothing in the repository.

The crate split is deliberate and worth a sentence for the security-minded: the CI verifier cannot sign — it never opens an agent session or touches a keyring, so a pull-request run has no signing capability at all.

The VTA and AI agents

One memory. Many agents. Yours.

laptop agent coding session phone agent on the move server agent running overnight own grant own grant own grant YOUR TRUST AGENT memory · audited · backed up scoped to one trust context revoke any agent with one command
The same memory, from anywhere — over TSP, DIDComm or REST, chosen per agent automatically, and none of it living in a vendor's product.

Every AI tool that remembers you keeps that memory in the tool. Its model of you is the most sensitive thing it holds, and it lives in somebody else's product — one per vendor, none of them yours, none of them shared.

Here memory is ordinary Trust Tasks against an agent you control. Scoped to one trust context, audited, and inside the encrypted backups. Any machine can be granted access, and revoking one is a single command.

Enrolment, the stack's standard flow

A throwaway identifier is minted, you grant it from anywhere — another laptop, CI, a colleague reading it off a ticket — and it rotates itself away on first use. The identifier that travelled through a low-trust channel stops being an authenticator.

Least privilege by default: a dedicated identifier, one context, the smallest role that can reach memory. The memory service is not you.

The picture is the pitch. Three agents on three machines, one memory, one owner. Today each of those agents has its own private, unexportable notion of you.

This is also the payoff for Act III. Nobody wrote transport code for this plugin — it gets TSP-or-DIDComm-or-REST selection for free, per agent, because the dispatcher and the identifier documents decide. Point back explicitly.

The rotate-on-first-use rule generalises well beyond this tool: the identity you paste into a ticket should stop working once it has been used.

Two boundaries drawn on purpose, if asked: memory is not application state — "forget everything" has to stay safe to ask — and memory is not a secret store; those are different capabilities in the agent.

The Claude Code plugin

The skill is the product. The tools are the easy part.

Six MCP tools

memory_recall · memory_get · memory_save · memory_forget · memory_list · memory_context

A skill, and this is the value

agent-memory says when to save and recall, what is worth keeping, and what must never go in. A tool that can write memories without a policy for what deserves one makes the session worse, not better.

Four commands, and a hook

/remember · /recall · /forget · /memories, plus a SessionStart hook that loads your memories before you type anything — so the model never has to remember to ask.

Two design rules worth stealing

  • Recall returns descriptions, not bodies. Bodies come back only from an explicit memory_get. A memory service that pastes every body into the context window has made the session worse.
  • Ranking is weighted token containment — name 4, description 2, body 1. Crude and predictable, chosen over embeddings because a scoring function nobody can predict is worse than one everybody can.

Two boundaries, drawn on purpose

  • Memory is not application state. “Forget everything” has to stay a safe thing to ask, which it stops being the moment account state lives there. That is what vta/app-state/* is for.
  • Memory is not a secret store. The VTA has a secrets vault and a credential vault, gated on different capabilities, deliberately.

Say the headline as written and mean it. Six MCP tools is an afternoon. The skill — the written judgement about what is worth remembering and what must never be written down — is the part that decides whether the feature helps or quietly poisons every future session.

The description-not-bodies rule usually gets a nod from anyone who has built retrieval. It is the difference between memory that helps and memory that eats the context window.

Both boundaries were arrived at by nearly getting them wrong. "Forget everything must stay safe to ask" is a user-facing property that dictates an architectural one.

Cost note if asked: recall reads the whole context, because memory/list has no prefix or cursor. Fine at the hundreds of memories a person accumulates — and the fix, if it stops being fine, starts with a spec PR to the public registry, because the VTA's dispatcher refuses URIs the registry has no schema for. That constraint is Act IV doing its job.

The wider bridge

An MCP host approves a tool, not a call.

Bridge your agent's whole management surface to any MCP-speaking host and you hit a problem worth naming: a host approves a tool once, and then every operation rides that one approval.

So the bridge carries its own policy on top of the access-control list — because the ACL bounds what the identity may do, and this bounds what this session may do.

read-only
Refuse anything not read-only, whatever the ACL permits.
allow / deny
Operation globs. Deny is checked first.
confirm
never · destructive · sensitive · always — ask a human in the host. If the host cannot show a prompt, the call is refused, not waved through.
enroll
Register the bridge as an AI-agent device, so disabling or wiping that device revokes it — enforced at authentication.

And the third layer — the one that matters most

Your agent can still demand a human

The bridge's flags are local to the machine running it, so a compromised host could ignore them. Your approver policy cannot be ignored — it lives in the agent, next to the keys.

Name an operation in require_consent and no AI agent can perform it, through any host, until a named approver signs on a second device. Exactly the ceremony from Act V, applied to a robot instead of a website.

Where the guarantee stops

Releasing a secret returns cleartext into the model's context, and issuing a presentation signs with a holder key in that process. Both are deliberate, and both are the two places where “nothing leaves the agent” stops being true. They are named in the README, not discovered later.

Three questions, three layers: the ACL bounds the identity · the flags bound the session · the approver policy bounds the individual act. An AI agent is just another enrolled, revocable consent surface.

"An MCP host approves a tool, not a call" is the line to leave the room with if they build agent integrations. It is a general property of the protocol, not a criticism of any host, and almost nobody has designed for it.

The purple card is the answer to the obvious objection — that local flags are only as trustworthy as the machine enforcing them. Say it plainly: local policy is advisory, agent policy is not. That is why the step-up ceremony matters more for AI agents than for browsers, not less.

The two named exceptions are the credibility move again. A security boundary with two documented holes beats one with two undocumented ones.

Demo

Enough slides.

Seven stops. Everything you have just heard about, running — and the last one is the one I actually want you to notice.

Run the demo as one uninterrupted block. We learned this the hard way on an earlier deck: narrating a demo slide-by-slide forces constant alt-tabbing and kills the momentum. Talk it through on slides first — you just did — then run it start to finish.

Show the map on the next slide, leave it up for five seconds so the room knows where they are, then switch away and do not come back until the end.

If anything breaks, keep going. You have the whole deck behind you; a failed stop costs you a stop, not the argument.

Where we are going

Seven stops.

1
Hosting
Geoff and Vincent's DID hosting service. Somebody has to run identity infrastructure — here it is.
2
A community, managed
A VTC: its policies, its roster, its credentials. Governance somebody actually wrote.
3
Joining it, end to end
OpenVTC from cold start to member — onboarding, the join, and the credentials that come back.
4
Memory
An AI agent that remembers me, out of my own agent rather than somebody's product.
5
Logging in as myself
The browser plugin. A real website, no password, no account — just me, provably.
6
Asking permission
Delegated execution: something proposes, my phone approves, my keys never move.
7
The disappearing act
Claiming an agent name — which is a DID document edit, done through the whole consent ceremony. You will not notice any of that happening.

Stops one to six are the stack doing its job. Stop seven is the stack getting out of the way — and that is the one that matters.

Five seconds on this slide, then go. It is a map so the room can place themselves, not a thing to read out.

Credit Geoff and Vincent by name on stop one. It is their service, the room should know the stack has more than one pair of hands on it, and it makes the whole thing feel like a team rather than a slide deck.

The arc is deliberate: infrastructure exists → a community exists → a person joins it → their agent remembers them → they use it somewhere real → something asks permission → and then the technology vanishes. Do not reorder it. Stop seven only lands because six earned it.

Pre-flight the delegated-execution stop especially — enforcement off and empty approver sets both fail silently, in opposite directions. Rehearse the full loop on the machine you will present from.

What that just showed

The best part was the part you didn't notice.

Stops 1–2
Identity infrastructure you do not have to trust, and a community running rules it wrote itself.
Stop 3
A stranger became a member, and walked away holding credentials nobody can quietly delete.
Stop 4
An AI agent with a memory of me that is not in a vendor's database.
Stop 5
A login with no password and no account — the site learned who I am without being told a secret.
Stop 6
Something I do not trust got work done by my agent, and never came near a key.
Stop 7
I claimed a name. Under it: a signed document edit, a rehearsal, a fingerprint, a human approval and a re-check. It looked like typing a name.

Infrastructure has succeeded when nobody can see it. Stop seven is what all of this is for — and it is the only slide in two hours where the right reaction was “…is that it?”

Come back to this slide immediately after the demo, while it is still warm. Each row ties a stop to the act that explained it, so the room gets the "oh, that is what that was" moment.

Land the last line properly. Every other stop is impressive because you can see the machinery. Stop seven is impressive because you cannot. That is the actual bar for infrastructure, and it is a good note to hand back to the closing slides.

If a stop failed during the demo, say which one and move on — the row is still true, and the deck already told them how it works.

Before you go build on it

The code is solid. The specs are moving.

Those are two different kinds of risk and they deserve two different answers. Conflating them is how people either over-trust or dismiss the whole thing.

The implementation · solid, running, tested

  • The agent and the community service, and the provisioning between them
  • Messaging end to end — mediators, multi-hop routing, and the delivery layer above them
  • TSP and DIDComm both, selected per peer from the identifier document
  • Delegated execution — the rehearsal, the fingerprint, the second-device approval, the re-check
  • The DID hosting service — server, witness, watcher and control plane
  • Commit signing and registry-backed CI verification
  • Sealed transfer everywhere a secret crosses a boundary; continuous fuzzing on the envelope and hosting paths

The specifications · public, live, and still arguing

  • TSP is an Experimental Implementer's Draft against a 0.x library — we build on it deliberately rather than waiting for 1.0
  • DTG Core Credentials is at Working Draft 01, with one live encoding divergence in witness credentials
  • The delegation credential is a proposed seventh type, in a pull request, absent from the published catalogue
  • Trust Task governance and the maturity ladder are being firmed up in the open

What that means for you: build on the code today. Expect wire-format details to move, pin your versions, and follow the working group — or better, come and argue in it.

If you take one habit from this stack, take this one: the honest list is a slide, not an appendix. Every claim in the last two hours is checkable against code you can read.

Never cut this slide for time. A workshop that oversells gets found out in week two, and then nothing else you said counts.

The spec-versus-code split is the honest frame. "Is it ready?" is the wrong question; "which part, and ready for what?" has a real answer. The code has been live-validated; the specs are drafts being argued in public — which is what a draft is for.

If someone asks what would change your mind about the design: the consent-matching ceremony is the piece most likely to be defeated by real user behaviour, and it is the one we watch hardest.

Monday morning

Pick one and start.

Just read
The First Person Project white paper by Drummond Reed, Martina Kolpondinos, and FPP contributors — the argument, not the mechanism. Start here if only one thing.
Understand it
The VTI concepts overview — the shortest complete picture of the agent and the community service.
Run something
vti-setup — organised by who you are, not by which service you are touching. Pick a role, follow the path, end with something running.
Stand it up
Cold-start an agent, then put a community on top of it.
Point an agent at it
Durable memory for your AI coding agent in your own VTA, and an MCP bridge to the whole management surface. Both enrol least-privilege and revoke with one command.
See a graph
dtg-demo → build → open. Deterministic, seconds to run, every credential real and signed.
Discuss & debate
The specifications are an open ToIP working group. Bring the disagreement — issues and proposals in the open; sign your commits off.

A digital twin you own · operations with names · sequences you can specify · and a stranger who can ask but never take. We are at the very start of this.

Close by repeating the through-line from slide 8 — the idea and the three things it unlocked. Bookending them is what makes them stick.

Push people at vti-setup over the documentation tree: it is role-organised and it is the only door that ends with something running on their own machine.

Then the QR slide, and open the floor. Anchors for Q&A: 7 (the ToIP stack), 30 (the delegated-execution flow), 42 (the join ceremony).

Everything, in the open

Take it with you.

First Person Project
the white paper
Trust Tasks registry
trusttasks.org
Trust Tasks framework
trustoverip/dtgwg-trust-tasks-spec
Trust Task specs
trustoverip/dtgwg-trust-tasks-tf
DTG Core Credentials
trustoverip/dtgwg-cred-spec
VTI · agent + community
OpenVTC/verifiable-trust-infrastructure
OpenVTC
OpenVTC/openvtc
Commit trust · VGI
OpenVTC/verifiable-git-infrastructure
Agent memory
OpenVTC/vta-agent-memory
DTG credentials · Rust
OpenVTC/dtg-credentials
Trust Development Kit
affinidi/affinidi-tdk-rs
DID hosting
affinidi/affinidi-webvh-service
Trust registry · TRQP
affinidi/affinidi-trust-registry-rs
did:webvh
decentralized-identity/didwebvh-rs

Specifications are ToIP Decentralized Trust Graph Working Group deliverables, developed in public. Implementations are Apache-2.0. Nothing on this page needs a login.

Leave this on screen for the whole Q&A. It is the most useful thing in the room while people are asking questions, and it saves you reading URLs out.

If you only point at three: the white paper for the argument, trusttasks.org for the registry, and verifiable-trust-infrastructure for the code.

Everything here is public and needs no account. Say that — it is the difference between a workshop and a sales pitch.

You already have a digital twin.
Let's go and get it back.

Thank you

Last slide. Say the line, then stop. It closes the loop opened on slide 2 — the whole deck is the answer to that opening sentence.

Then go back to the QR wall and leave it up for questions.