A note before we start. I do not normally write here about what I do for a living, and that is deliberate rather than coy. Writing about your own work from inside it is bad for the writing, which quietly turns into advocacy, and bad for the work, which starts being done with one eye on the audience. So this site tends to stay on the general side, on the arguments rather than on the desk I happen to argue from.
This time I am making an exception, and I am claiming it as one. What follows is not about my job. It is about something I built in the evenings for fun, which happens to be set in the only subject I know well enough to make jokes about. Normal service, meaning arguments about things considerably larger than me, resumes afterwards.
There is a sound that a certain generation recognises before it remembers it. It is not a note, it is a sequence: the dial tone, then the whistle, then that stretch of electrical sand that lasted about seven seconds and ended in a click. If you were fifteen and you owned a modem, that sound meant you were about to go somewhere, at night, quietly, with the household phone bill running as a timer.
And there was the phrase it all ended with, late in the evening, when the line dropped or when your daily time on the node ran out.
NO CARRIER
Two words in capitals. No explanation, no retry button. The place you had been in simply was not there any more.
Right. I have spent the last few weeks building something whose last act ends with exactly those two words, and in between there is the European digital identity framework. I owe you an explanation.
I should be honest about the audience first. This is a piece for people who recognise that modem sound and also know what a relying party is. I have done the arithmetic and I believe there are around four hundred of us in Europe, most of whom I have sat in a room with. If you are one of the four hundred, this article is a gift and you may skip to Part three. Everyone else is very welcome, but you will need to be patient twice. The thing itself is called TRUST ANCHOR, it runs in a browser, and it is here. The rest of this is why.
Part one, in which I explain what a MUD is to anyone born later
In the mid-1970s a programmer called Will Crowther, a caver in the middle of a divorce, wrote a program that described a cave in words and let you walk through it by typing. His day job had been the routing code for the ARPANET's interface message processors, which is to say the packet-switching logic of the network that eventually became the one you are reading this on. The man who paved the roads also built the first place worth going to. I find this consoling for reasons I cannot entirely defend.
A year later Don Woods expanded it, and the result is what everyone simply calls Adventure. Out of it came a line that has been folklore in computing ever since:
You are in a maze of twisty little passages, all alike.
Anyone who has played knows that line does not describe a room. It describes a state of mind.
Then came Zork and the grue, the invisible thing that eats you if you turn off the lamp, and which nobody has ever seen because by definition you only meet one in the dark. The word was borrowed from Jack Vance, who had used it for something considerably worse and considerably less funny.
And in 1978, at the University of Essex, Roy Trubshaw wrote something that took the text adventure and added the ingredient that changed everything, other people. Richard Bartle took it over and turned it into a world. They called it a Multi-User Dungeon. MUD. A world made entirely of text, which you enter by typing, and in which you find other human beings doing the same. No graphics, no sprites, nothing to install. Just descriptions, verbs, and the physical sensation of being in a place that does not exist. Bartle spent the following decades cataloguing the four kinds of person who turn up in one, the last of which exists purely to ruin the evening for the other three. The taxonomy has aged better than almost anything else from 1978 and describes, without modification, every standardisation body I have ever sat in.
Where I grew up, all of this arrived over bulletin boards. You dialled a number, engaged, dialled again, engaged, dialled again, and occasionally you got in. You found the message areas, the echomail hopping from node to node overnight across Fidonet, the turn-based door games where you got one move per day, and the benign tyranny of the SysOp, who knew you by your handle and who at two in the morning was somehow still awake.
It was a network built by people trusting other people according to rules written by hand, and it worked.
I grew up inside that. Then life moved along, and now I work on European digital identity, which on reflection is still a world made of text in which people trust each other according to rules written by hand, only with more annexes.
Part two, in which I explain why I did this
The European Digital Identity Wallet ecosystem has a storytelling problem, and the problem is not that it is complicated. The problem is that it is tedious to explain and rather wonderful to use, and those two facts almost never end up in the same room.
Take the best part of it. A bar has to establish exactly one fact about you, that you are old enough to drink. The traditional method is that you hand over a document stating your given name, your surname, your date of birth, your place of birth, your nationality, your home address and a unique national identifier, and the barman reads one of these seven things and ignores the other six, having nonetheless now seen all seven. The new method is that your wallet hands him a single bit, signed by an issuer he has reason to trust, which says age_over_18 = true and almost nothing else about you.
Almost, because it also shows him who signed it, and an issuer points at a jurisdiction. Not at your nationality, not at where you live, just at the authority that vouched for you. That gap between nothing and almost nothing is not a footnote. It is an entire act of the game.
I think this is a small marvel of public policy. Now try putting it on a slide. It becomes four rectangles and a dashed arrow, and the person looking at it nods and feels nothing. I have given that slide. I have also been that person.
Then one afternoon I noticed something that had been sitting in front of me for years: that is not an explanation, it is a puzzle. There is a goal, get the beer. There is an obvious wrong solution, hand over everything. There is a non-obvious right solution, hand over one bit. And there is a character who asks for far too much without being a villain, because he is not a villain, he is just badly habituated.
The game did not need to be invented. It was already inside the rules. Somebody just had to take the rectangles off it.
Part three, in which reality turns out to be funnier than invention
It is called TRUST ANCHOR, and before anything else I have to give back the U.
I have just spent a section explaining that the great innovation of 1978 was other people, and I am about to show you a game that contains none. TRUST ANCHOR is single-player. There is nobody else in Bruxellia, no application server, no account and no shared state. There is a web host, obviously, because the files have to come from somewhere, but once they arrive the game has no telemetry and learns nothing about how you played. Strictly speaking it is a text adventure, and the twenty years of MUD furniture I have just carried in here belong to something I did not build.
Except that this is not quite true, and the way in which it is not true is why I kept the furniture. The other players are present, they simply left before you arrived. The issuer who signed the credential in your pocket. The registrar who recorded what the barkeep is permitted to ask for and why. The supervisory authority that will eventually read the complaint you can file in act three. Every one of them acted on you in advance, and you meet them only as signatures, entries in a register and lines in a trust list. Which is exactly how Fidonet worked. Nobody needed to be online at the same moment. You dialled in, you found what other people had left overnight, and the world was unmistakably populated.
So it is a Multi-User Dungeon in which the other users are institutions, and institutions do not answer in real time. They answer in advance, in writing, and then go home.
It runs in your browser, set in a city called Bruxellia which is simultaneously a European capital and a bureaucratic cathedral. The line it boots with is, inevitably:
You are in a maze of twisty little implementing acts, all alike.
In the first act you wake up with a freshly issued wallet and a modest objective: a beer. On the way there is an alley with a hooded figure offering verification, no questions asked, who then asks you fourteen questions. And there is a tavern where the barkeep requests eight attributes in order to check one.
> INSPECT REQUEST
PRESENTATION REQUEST, inspected
Requester ......... "AU BON ATTRIBUT SPRL", tavern
Registered ........ yes, in the register of relying parties
Intended use ...... "verification of legal drinking age"
Requesting ........ given_name, family_name, birth_date, birth_place,
resident_address, nationality, personal_administrative_number,
age_over_18
Accepted formats .. as a document, or as a token. Either. Both. The tavern
does not care and has never once been asked to care,
which is the entire achievement.
(The register entry immediately below this one, for a fireworks shop two
streets over, consists in its entirety of the words "Mostly harmless.")
Your wallet, gently, as if to a child:
"He has registered to check ONE thing. He is asking for EIGHT. Seven of them
he has no business seeing, and the eighth is the only one that answers his
question. You may present just that one. You may also REFUSE. You may also
hand him everything, in which case I would like it noted that I said
something."
> PRESENT AGE_OVER_18
You present exactly one attribute: age_over_18 = true.
Not your name. Not your birth date. Not the street you sleep on. A single
boolean, signed by an issuer he trusts, which answers his question completely
and tells him nothing else about you at all.
The barkeep stares at it. He turns the tablet over, as if the rest of you
might be printed on the back.
"That's it?"
"That's it."
"That's..." he searches for the word, "...that's not very much."
"It's exactly enough."
There is a long silence, during which a small and genuine miracle of European
public policy sits quietly on a bar tablet between two men, and then he pours
the beer, because the beer was never really the difficult part.
Outside, you notice the PID PROVIDER standing in the street with his fingers
in his ears and his eyes shut, singing loudly.
"LA LA LA I CANNOT HEAR WHERE YOU ARE SPENDING YOUR ATTRIBUTES LA LA LA."
You could point out that he could simply not look.
"I am a public authority," he says, without opening his eyes. "'Simply not
looking' is not a control. THIS is a control."
The barkeep is the most useful character in the game, because the framework has an answer to him and the answer is not a moral one. A wallet relying party has to register, and has to declare in advance which attributes it intends to request and for what use. Registration does not turn an excessive request into a legitimate one: minimisation still applies, and asking for more attributes than it registered can cost the relying party its registration. What registration does is make the excess visible, comparable, and actionable.
The barkeep is welcome to want your place of birth. He simply has to write down, in a public register, that establishing whether people may drink beer requires knowing where they were born. This is the part of the architecture that most resembles a joke and is not one. It works the way jokes work: you say the thing out loud in front of witnesses, and then you have to live with it.
There is one discipline in the writing that I will admit to, because it is the only thing that kept the project from becoming another tired complaint on the internet. Every joke about a design decision has to have a second beat in which the decision turns out to be right. Two lines making fun of one-time-use batched attestations, and then two verifiers actually trying to correlate you and failing. Without the second beat you are not doing satire, you are doing sighing, and the global supply of free sighing about this subject already comfortably exceeds demand.
But the thing I actually want to tell you happened while I was checking the text against the official acts, to make sure I was not teaching people nonsense.
There is an official at the very beginning of the game who looks at you through a glass panel and says: before I can give you the proof that you exist, I will need to see some proof that you exist. I wrote that as a gag about onboarding.
Weeks later I was reading the implementing regulation on the certification of wallet solutions, Commission Implementing Regulation (EU) 2024/2981, Annex IV, point 6(4), on how the operating effectiveness of a provider's maintenance processes is assessed. It observes that a wallet solution is not permitted to operate before it is certified, that operating effectiveness therefore cannot be confirmed on the basis of actual operation, and that it must instead be demonstrated through tests or pilots.
Translated: you must demonstrate that you can operate before you are permitted to operate.
The joke I had written for the citizen was, in substance, the real position of the provider. I did not discover this by writing the game. I discovered it by writing the same scene twice, at two different scales, without noticing. Once I saw it I rewrote half the project around the rhyme.
This is the real reason people build apparently useless things in their spare time. Not for the result. For the thing you can only find out on the way there.
Part four, in which there is no language model, and I expect to be argued with
The project started as a hybrid: a deterministic game world plus a language model playing narrator and characters. It looked like the modern choice, and it was the correct choice right up until the moment I had the text.
Then I finished all three acts and changed my mind. The published game uses no language model at runtime, for four fairly concrete reasons.
Comedy does not survive paraphrase. The value of a joke is the exact rhythm and those particular words. A model rewording it produces something reasonable, fluent and slightly worse. Every time, for every player. Timing is the whole asset and it is the first thing to go.
A terminal from 1988 answered instantly. The game presents itself as one. A second and a half of spinner per turn is an anachronism you feel in your hands before you can name it.
Generation has a tail. However tightly you anchor it to a file of verified sources, there remains a band of probability in which the thing says something confident and wrong about the legal framework. That tail has negative expected value and buys me nothing, given that the correct text is already written and does not vary from one playthrough to the next.
Without a model the game is static. No inference cost per turn, it scales the way static content scales, there are no keys to rotate and no application backend of mine to fall over at three in the morning. The 1988 aesthetic turns out to cost far less to run than 1988 did, which is the best joke in the entire architecture and I did not write it.
The model was extremely useful everywhere else: drafting, reviewing, checking every claim against the sources, holding a canon together across three acts. That is authorship, not play, and the distinction matters rather more than the technology does.
Which brings me to the third level of the rhyme, which I only noticed at the end. The citizen must prove he exists in order to be given the proof that he exists. The provider must demonstrate operation in order to be permitted to operate. And I had to write the whole game, three acts, every joke, before I could discover that the finished game did not need a model inside it. In each case the only way to find out was to do the thing first and be entitled to it afterwards. I would like to claim I planned this. The repository is public, so you can check the commit history and confirm that I did not.
How to play
Act One is playable now. Acts Two and Three are written and are being released.
You open a page and you type. Nothing to install, no account, no cookies, no analytics. Once the files have loaded, the game makes no further requests and keeps nothing about how you played. The host logs the requests used to deliver the page, as hosts do, and that is the whole ledger available outside your browser.
Useful commands to start with: LOOK, TALK TO BARKEEP, INSPECT REQUEST. After that you decide what to present, and my advice is to get it deliberately wrong at least once, because the bad endings are considerably better written than the good one.
There are also things you will not find unless you go looking. Try XYZZY. Try 42. Try opening the mailbox in the square. And if you read the Regulation more than once, the game notices. It does not reward you. It notices.
The code and all of the text are public, along with the acceptance tests, the design document, and the file of legal sources from which every factual claim in the game has to come. If you find a substantive error, open an issue. It is a satirical game, but on the real things it wants to be right, and I would rather be corrected than quoted.
There is one final verb the parser does not implement, and it is CONTRIBUTE. That one runs on GitHub, and three things would genuinely help. A scene, because if there is a corner of this framework that irritates you professionally, it is almost certainly a room, and the room is almost certainly funnier than the recital that describes it. A translation, because the game is in English, which for a European project is at best a working assumption. And a bad ending, because the bad endings are where the teaching actually happens and I have only written the ones I could think of.
I am away for a few weeks, so anything opened tomorrow will sit there for a while. It will be read. Asynchronous, in writing, and nobody needs to be online at the same moment, which by now you will recognise as the house style.
Play it here: https://trust-anchor.cyberverso.net/
Code, text and sources: https://github.com/cyberverso-net/trust-anchor
One last note, serious even though the rest is not. This is a personal project. It does not represent the position of any institution, it is not legal advice, and where the game and the Official Journal disagree, the Official Journal wins. It always wins. That is more or less what it is for.
But you can get the beer with a single bit. That is also what it is for.
NO CARRIER