Picture the moment a regulator actually shows up. Not the hypothetical regulator from the slide deck. The real one — Tuesday, 10am, a refused loan applicant has filed a complaint under Article 86 of the AI Act and somebody at the bank needs to reconstruct, in under an hour, exactly why application #17492 was refused. That’s the moment most automated-decision stacks discover what they don’t have.

Article 86 says the affected person has a right to “clear and meaningful explanations of the role of the AI system in the decision-making procedure and the main elements of the decision taken.” Article 12 says the decision is supposed to be logged over the system’s lifecycle. Article 13 says the operation has to be disclosed in a form the user can understand. Article 15 says the system has to be accurate and robust by design. Four separate paragraphs in a regulation, and in most stacks they live in four separate places — a Confluence page, a decision-engine codebase, an ad-hoc rejection string, and a Splunk dashboard. The drift between them is invisible until the morning somebody asks where, exactly, the explanation came from.

What I want to write about is the version where those four answers come out of the same two files on disk.

The standard pattern

The way this normally goes: there’s a decision service somewhere. Python rule engine, model behind an API, microservices wired through a queue. The team has done the work — there’s documentation, a log pipeline, a notification template for refusals. Every piece exists. The piece that doesn’t exist is the chain that ties them. The doc lives in Notion. The code lives in git. The log lives in S3. The rejection email lives in a Mandrill template. Each was true at some point. Each can quietly stop being true, because no machine compares them.

When the regulator asks “show me the explanation given to applicant #17492,” the answer is assembled at request time, from four sources, by a person under deadline pressure. The chain isn’t false. It’s just not mechanical. Which means it depends on the team being disciplined, the headcount being stable, the priorities not slipping. Those things slip.

This isn’t a complaint about the teams. They’re doing what the tools let them do. The tools were built for a world where accountability didn’t have to be visible. Article 86 changed that world.

The realization

I’ve been working on verbose — a small language whose architecture is “the author declares, the binary doesn’t drift.” Every read named in source. Every effect declared at top level. The compiler refuses to emit a binary that does anything the source didn’t say. For a while I described this as “code you can verify,” which is technically true and rhetorically wrong — it makes it sound like the work is the verification, when actually the work is making the responsibility visible.

An auditor under Article 86 doesn’t need the binary to be smart. They need the binary’s behavior to be readable from one place. That’s the move. Compliance regimes don’t invent accountability — they make accountability legally enforceable. The author is on the hook either way. What changes is whether the hook is something you can point at.

What this looks like

There’s a worked example in the verbose repo for an Annex III point 5(b) high-risk decision — automated loan creditworthiness. Two files. The first one, loan_decision.intent, is four numbered sentences in plain prose:

1. A loan applicant has an annual income, a credit score, an employment
   duration in months, and a count of recent defaults.
2. A loan application is approved when the applicant's income is at
   least 25000, their credit score is at least 600, their employment
   has lasted at least 6 months, and they have zero recent defaults.
3. When approved, the authorized loan amount equals thirty percent of
   the applicant's annual income.
4. When refused, the first failing criterion is reported verbatim as
   the explicit reason for the refusal.

That file is the Article 13 disclosure. A regulator can read it without knowing any code. A refused applicant can read it. The product team can read it. It is the single place where the rule’s intent lives in prose.

The second file, loan_decision.verbose, is the formal version the compiler accepts. The decision body looks like this:

decision = if i.income < 25000 then
             Err("income below minimum required 25000")
           else if i.credit_score < 600 then
             Err("credit score below required 600")
           else if i.employment_months < 6 then
             Err("employment stability below required 6 months")
           else if i.recent_defaults > 0 then
             Err("recent defaults on record must be zero")
           else
             Ok(i.income * 3 / 10)

The thing to look at is the string inside each Err. That text is the explanation Article 86 requires. Not a separate template that has to be kept in sync. Not a constant in a notification service. The plain-language reason the affected person gets — and the reason that lands in the audit log — is the same literal in the same file.

The rule also carries a declared reads: list (the four fields it touched, no more), a termination bound (the verifier proved it halts in at most 15 operations), and a @source: loan_decision.intent:2 reference so the verifier rejects the build if the prose file moves out from under it. That’s Articles 15 and 17, structural and not optional.

What the auditor actually does

Tuesday morning, application #17492. The auditor opens the JSONL log, finds the line:

{"ts":1778580000,"input":"15000 650 12 0","verdict":"refused",
 "reason":"income below minimum required 25000"}

That string is the same bytes the applicant got in their refusal letter. The auditor knows this not because somebody promised, but because the only place that string exists in the source is the first Err branch, the rule’s declared reads are exactly the four fields in the input, and the binary is downstream of that single .verbose file. The chain prose → formal source → binary → verdict → audit line → user-facing reason is one path, and every step is either a human-readable file or a mechanically-verified translation.

The audit takes minutes. Not because verbose is fast — because there’s nothing to investigate. The work that would normally happen at audit time was done at compile time, once, structurally.

Why I prefer this for the regulated slice

I want to be careful. This isn’t a claim that verbose solves AI Act compliance. It doesn’t. Article 10 — data governance for training data — is unaffected if your thresholds came from a model. Article 14, human oversight, is an organizational wiring choice. Article 22 of GDPR, the right to contest, needs a workflow nobody’s compiler can build. Verbose addresses one slice: the decision artefact itself, and the audit chain from that artefact.

But it addresses that slice in a way I haven’t seen another tool address. The link between the prose, the formal source, and the user-facing reason isn’t a process discipline. It isn’t a CI check that can be skipped. It isn’t a Confluence page that can drift. It’s a property of the build — if the source files disagree, the binary doesn’t exist.

The cost is the part most stacks try to avoid: the author has to write down what they meant, in prose, in numbered sentences. There’s no framework to do this on their behalf. I’ve come to think that’s the feature, not the bug — the regimes were never going to let the author off the hook. Article 86 says, in writing, that the author is responsible. The architecture refuses to pretend otherwise.

What this is not

It’s not “verbose makes you AI-Act-compliant.” Nothing makes you compliant. Articles 10, 14, 22, 72, the conformity assessment under 43-49 — those are organizational and procedural, and no compiler is going to do them for you.

It’s not “rule-based decisions are the right shape for every high-risk use case.” Plenty aren’t. A clinical risk score derived from a trained model isn’t going to fit in five Err branches, and pretending it would be honest is its own compliance failure.

It’s: when a regime says the author is responsible, an architecture that makes the author’s claims mechanically inspectable is the version of the work that survives Tuesday at 10am. The bytes the auditor reads are the bytes the user got. That’s not a guarantee about the quality of the rule. It’s a guarantee about correspondence. Correspondence, when the regulator is at the door, is most of what was missing.