bAIbel
/technology

What is actually built

Two products, built on one engineering position.

The position is this: a translation system that puts a language model in front of a client's documents is making a series of decisions on that client's behalf — what the AI model sees, where it sits, what it costs, what gets kept — and almost all of the difficulty is in making those decisions checkable rather than in making them at all. A control that reaches the right answer and then discards it is easy to build and impossible to detect from the outside.

So this page is about six things: what leaves the machine and in what form, what is enforced rather than promised, how much of the document the AI model is given, where a language model is the wrong tool entirely, what the system records about its own decisions, and what survives a file's trip to another tool and back.

Chapter 1

The confidentiality chain

Substitution

Redacting a client's material breaks it. An AI model given "[REDACTED] reported that [REDACTED] had acquired [REDACTED]" produces worse output than an AI model given nothing, because it now has a structure with holes in it and will fill them.

So confidential material is replaced, and what it is replaced with depends on where the system learned about it.

Material a client's profile declares — the names, entities and terms they have listed — is replaced with an inflected stand-in: a name that reads like the real thing, grammatical in the target language and matchable downstream, so a translation memory lookup, a terminology check and a consistency pass all still work on the text the AI model saw. An AI model given stand-ins reads a document that makes sense; given blanks, or placeholder after placeholder, it loses the sense of the original.

Material the run's own scan discovers is replaced with a placeholder. This is the more interesting case, because the first design replaced the stand-in engine with the placeholder engine and had to be changed: a discovered surface is a string nobody has declared a grammar for, and a stand-in nobody can inflect or match is worse than a placeholder. So the two transforms are composed rather than substituted for one another. Known material gets a name it can live with; discovered material gets a placeholder, and a placeholder is at least honest about being one.

Alongside stand-in names, on the desktop, sit two further kinds of protection: figures scaled to believable stand-ins, and email addresses, phone numbers and house formats swapped for placeholders by rule, with no model involved at all. Percentages get placeholders rather than being scaled, because scaling a percentage changes what it means.

One caveat travels with the scaling claim wherever it is made, including here: one factor preserves every ratio. A reader who knows one real figure can recover the rest. It is a disguise, not encryption, and it is offered as one.

What stand-ins do, and what they do not

Stand-ins are a layer, not a guarantee. What they add is real: the client's names, figures and identifiers are replaced before the request leaves your machine, so they are not in it while it travels, and not in what the AI model's provider receives, processes, logs or keeps. Whatever happens to the request after it leaves, the real names were never in it.

What they do not do is make the rest of the question go away. A stand-in covers what the profile declares and what the scan finds, and nothing else: the facts around a name, the subject of the document and the shape of its figures still travel. The link between each stand-in and the real thing stays with you, which is why this is pseudonymisation, not anonymisation, and why the text sent is still personal data wherever it was before. Whether a client's material may go to a given provider at all, under what agreement and in which region, is a separate question, and stand-ins do not answer it.

Regulatory surface — the regulatory surface, including the parts stand-ins do not reach

NOT REDACTION [REDACTED] reported that [REDACTED] had acquired [REDACTED] A structure with holes in it. The AI model fills them, so this is worse than giving it nothing at all. WHERE THE SYSTEM LEARNED ABOUT IT WHAT REPLACES IT AND THEN Declared a client's profile declared it Discovered the run's own scan found it An inflected stand-in grammatical in the target language A placeholder honest about being one One protected text sent in place of the client's own STILL WORKS ON IT A translation-memory lookup A terminology check A consistency pass Composed, not one instead of the other. A discovered surface is a string nobody has declared a grammar for, and a stand-in you cannot inflect or match is worse than a placeholder. The first design replaced one engine with the other, and had to be changed. ON THE DESKTOP, TWO MORE KINDS Figures scaled to believable stand-ins; contact details swapped for placeholders by rule. Percentages are given placeholders, not scaled, because scaling a percentage changes what it means. ONE FACTOR PRESERVES EVERY RATIO A reader who knows one real figure can recover the rest. It is a disguise, not encryption, and it is offered as one.
Stand-ins, not redaction — two kinds of confidential material, two transforms, composed

An unreadable reply stops the call

A confidentiality control is only as good as its worst reading path, and the worst reading path is almost always a tolerant parser.

Consider what happens when an AI model returns a malformed reply to a question like "list every personal name in this text". A forgiving parser salvages what it can, finds no complete entries, and returns an empty list. The calling code sees an empty list and concludes there is nothing confidential in the document. A tolerant parser has turned an unreadable answer into a silent all-clear.

So the gateway refuses a reply its parser cannot read. Not degrades — refuses. And improving the parser into something that salvages a missing brace is a defect by policy in this codebase, not a missing feature, because the two properties cannot coexist.

The same discipline covers truncation: every live probe checks the completion reason before it reads the content, because a reply cut off at the token limit looks exactly like a reply that found nothing. And an empty confidentiality snapshot is treated as an inactive snapshot rather than as the absence of one, so a configuration that armed nothing cannot pass as a configuration that found nothing to arm.

Both products refuse the send

bAIbel TMS inspects the outgoing call and refuses it if a confidential term is still in it. The refusal throws out of the gateway; the engine records the run as refused, with its reason.

bAIbel AV audits every AI request for leaked names on every pathway that sends, finding each hit with its entry and its offset — and refusing the send. It keeps a record of the finding, with a surrounding window, only if you turn records on in Settings. A hit stops the send, and the message names the terms that were still in the request and the region each sat in. A quieter case refuses too: a profile you named that will not load protects nothing, and the audit has nothing to match against, so the text is not sent as written.

Both products fail closed (when a safeguard cannot do its job, the request is refused rather than sent). On the desktop that includes a profile that loads but arms zero matchers: it refuses the send like the others. Declining protection is a decision, taken in the project's settings; a profile that arms nothing is the case where somebody asked for protection and got none, and it no longer goes out as though they had not asked.

Regulatory surface · Confidentiality · The border

The part nobody expects

On bAIbel TMS, the stand-ins cover the operator's own prose about the client's document.

The document summary, the project description, the additional material, the cultural directives — somebody in the agency wrote those, so a naive system treats them as trusted and splices them straight into the AI model's instructions. But they are about the client's document, which makes them client-derived, which means they routinely contain exactly the names the stand-ins exist to replace.

So they travel as client texts with their stand-ins, behind markers, never in the clear, and the gateway refuses a call in which a marker was never placed. Not a warning, not a fallback to the plain text — a refusal.

Chapter 2

Policy enforced rather than promised

When bAIbel TMS decides whether a given model provider may receive a given client's material, it enforces exactly four facts about the provider: its trust tier, its registered region, an unexpired allow-list entry, and whether the covering instrument reaches raw content.

Four is a small number, and the smallness is the design. The rule the codebase holds itself to is that every field it enforces must be traceable to a clause somebody read. A field enforced confidently on a basis nobody can produce is worse than no field at all, because it converts an unexamined assumption into a green tick in somebody's review. Four fields that are all real beats twelve that are mostly aspirational, and it is the only version a reviewer can actually audit.

Around those four sit four rules about how policy combines, all enforced:

And one exemption that is deliberately not granted: in-house providers go through the allow-list like any other. An AI model the operator runs on their own hardware is still a sub-processor decision. This is the exemption most systems grant without noticing, and granting it is precisely how a self-hosted endpoint becomes the one route nothing checks.

TWO POLICIES, FOLDED A client's own policy what this client requires The deployment's floor what the operator requires of every run Fold — the stricter wins a residency conflict resolves to the floor One effective policy ALSO ENFORCED A lapsed agreement permits nothing — expired entries drop out Null means "not stated" never "everything" FOUR FACTS, ENFORCED 1Its trust tier 2Its registered region 3An unexpired allow-list entry 4Whether the instrument reaches raw content — the agreement contemplates the provider seeing the material, not metadata about it A third-party provider someone else's API An in-house model your own hardware The same gate. An in-house model is a sub-processor decision like any other — granting it is how a self-hosted endpoint becomes the one route nothing checks. may receive refused DOCUMENTED — A RULING, NOT A RUNTIME CHECK Custody and legal basis are two axes, never one score. Where the material sits and what makes it lawful to sit there are different questions; one score loses whichever was inconvenient.
The four facts, and the four rules that fold two policies into one

One thing is a ruling rather than a check, and is presented as such: custody and legal basis are two axes, never one score. Where material physically sits and what makes it lawful for it to sit there are different questions, and collapsing them into a single rating quietly loses whichever one was inconvenient.

Regulatory surface

Chapter 3

Document context rather than segment at a time

Machine translation has historically worked a segment at a time because that is the unit a translation memory stores. It is a terrible unit for a language model, which will translate "It depends on the context" identically in a legal opinion and a cookery column.

Both products translate from the whole document, and in both the unit sent is an authored section — a cut taken from the document's own structure, with a word cap sitting on top of that structure as a size guard rather than as the thing that makes the cut. This was traced independently in the two codebases, and the two carry the same core: the summary, the style, what the section is for, the terms, and the translation so far. That is confirmation from a second direction rather than a claim made twice.

But the size of the unit is the less interesting half. What travels with the section is the point. On the server, it is:

EIGHT NAMED THINGS TRAVEL WITH ONE SECTION 1 The document summary generated from the source, then yours to edit 2 The style you set for the whole document 3 What this part is for ordinary prose, a footnote, page metadata, interface strings 4 Instructions for this section anything you wrote for this section alone 5 The translations already made a window of what came before it 6 The termbase hits for the words actually in this section 7 Your project glossary and where the two disagree, the project wins 8 The run's cultural directives and the target-language stand-in for any protected name One section, cut along the document’s own structure The briefing you would give somebody competent who had not read the file. AND ONE THING THAT IS NOT ON THE LIST Formatting. It is not a ninth item, and it is not in this request at all. What the finished document looks like is the document pipeline, not the briefing — a different mechanism entirely.
The section and its briefing — eight named things going in with one section

The desktop's set, in the figure, adds the instructions you wrote for that section alone.

Which is to say: the machine is given what a briefed translator would be given. Not more text — a brief. A human translator handed a section with no idea what the document is, who it is for, or which of two renderings of a term this client uses, would produce the same kind of plausible, inconsistent, subtly wrong output that segment-at-a-time machine translation produces, and for the same reason.

Two details in that set are worth pulling out, because they are the kind of thing a working translator checks first. Where a term is defined in both the project glossary and a termbase, the project glossary wins and the termbase citation is dropped before the request is built — from one source of truth, so the two forms of the glossary cannot disagree. And a stage's absence means absence: a workflow that places no summarize stage and no functional-role stage translates without them, and nothing silently substitutes a default. An absent stage pretends nothing.

Machine translation · Workflows

Chapter 4

Where a language model is the wrong tool

A language model is a probabilistic instrument. Where the correct answer is derivable, asking an AI model for it is a category error — it replaces a verifiable computation with a plausible one, and the failure mode is not an error message but a confident wrong answer.

Inline-code integrity. The tags carrying bold, links, placeholders and line breaks through a translation are checked by a deterministic component with no model in the path at all. Whether a code is mandatory is derived from its element kind and its type together, stamped once on the source side, and never re-derived downstream — a target code is classified by the source code sharing its identity, not by looking at itself. A missing mandatory code fails the export validator, and nothing is written — the check runs before the file does. The refusal names the segment, names the code, and states what the loss would cost: the paragraphs will be rebuilt, but with no target-plus to divide the translation between them, only the first can carry any of it.

Sentence segmentation. Rule sets, for 66 languages — nine full, 57 basic. Not an AI model deciding where sentences end. Anything outside those 66 falls back to English rules, and the file records that it did — Evidence states that boundary in full.

Formatting resolution. What a paragraph displays is not what is written on it, and recovering the difference is a specification walk, not a judgement: document defaults, then the inheritance chain root-first, then direct properties, then the dominant run's character style chain, then its direct properties, with theme fonts resolved last — and the toggle properties (bold, italic, caps, small caps) XORed down the chain rather than overwritten, which is what the standard actually says and what naive implementations get wrong. It is intricate, it is entirely deterministic, and an AI model asked to do it would be right most of the time.

Merging a translation home. Target merge is by trans-unit identity, never by order. A table is resolved home by identity too, and where every unit does not resolve — or where two share an identity — the reply is refused rather than half-written. Guessing is available and is not taken.

WHERE THE ANSWER IS DERIVABLE, A MODEL IS THE WRONG INSTRUMENT It replaces a verifiable computation with a plausible one, and the failure mode is not an error message — it is a confident wrong answer. So in these five places there is no model in the path. Inline-code integrity No model in the path at all Mandatory is derived from element kind and type together, stamped on the source side once, and never re-derived. A target code is classified by the source code sharing its identity, not by looking at itself. Sentence segmentation Rule sets, for 66 languages Not an AI model deciding where a sentence ends. Everything outside those 66 falls back to English rules, and the file records that it did. Formatting resolution A specification walk, not a judgement Document defaults, the inheritance chain root-first, direct properties, the dominant run's character style chain, then its direct properties, themes last — with the toggle properties XORed down the chain rather than overwritten, which is what the standard says. Merging a translation home By trans-unit identity, never by order Where every unit does not resolve, or two share an identity, the reply is refused rather than half-written. Guessing is available, and is not taken. Retrieval The AI model composes the query; Lucene retrieves And the caps that stop a search becoming a whole-memory dump live in the tool layer, not in the instructions. A limit you ask an AI to respect is a request. And the same reasoning produces the doctrine about PDFs. A PDF is not a format to be parsed. It is converted first, by a step with its own provider choice — because a clean digital PDF, a scanned one and a forms-heavy one need different treatment at different cost, privacy and latency, and burying that choice inside an importer dialog takes a decision away from the only person qualified to make it.
Five places a language model is the wrong tool

Retrieval. Concordance search is agentic: the AI model composes the queries and Lucene does the retrieval. The caps that stop a search becoming a whole-memory dump live in the tool layer, not in the instructions — which is what makes whole-memory retrieval structurally impossible rather than merely discouraged. A limit you ask an AI to respect is a request. A limit written into the tool is a limit.

The same reasoning produces a doctrine about PDFs that both products reached independently: a PDF is not a format to be parsed. It is converted to Markdown or HTML first, by a step with its own provider choice — because a clean digital PDF, a scanned one and a forms-heavy one need genuinely different treatment at different cost, privacy and latency, and burying that choice inside an importer dialog takes a decision away from the only person qualified to make it.

File formats · How work arrives

Chapter 5

Provenance — what the system records about its own decisions

Every claim above is a decision the software takes on somebody's behalf. What makes those decisions worth anything is that the system writes down what it decided and why, in a form somebody can audit afterwards — and, more importantly, that it records the cases where it could not decide, rather than recording a default and moving on.

That is the pattern, repeated deliberately. Every example below is bAIbel TMS except one, the profile that arms nothing, which is the desktop.

A reading that could not be taken is a flagged gap, never a zero. When a cost reading cannot be taken, the run records it as unmetered. It does not record nought. Nought is a number, it sums correctly, it appears on a report, and it is wrong.

A safety margin is measured, not assumed. Where a budget gate pads an estimate before enforcing against it, the padding is the p90 of how wrong this workflow definition's own estimates have been, at this document size, taken from the variance sample recorded on every completed run. The multiplier stops being somebody's hunch and becomes evidence. Quoting uses the raw estimate; only enforcement uses the padded one.

A refusal names its arithmetic. When a budget refuses a run, the reason states the budget, what remains, of what, what was needed, and the multiplier that was applied — because a refusal nobody can act on is just an outage. And a budget that cannot price a run refuses it, rather than admitting spend nothing can bound.

A notification carries no reason. It names the run and says where to look. This looks like a missing feature until you notice what a reason would contain: a failure reason can carry an exception message, and a gate reason names what a detector found inside the client's document. A mail server is covered by none of the decisions anybody made about that material. So the message points at the run, and the run tells whoever signs in everything.

A delivery record says what kind of party received the document — filed where only the operator can reach it, collected by a person who signed in, or taken away by another company's software. Three kinds, kept distinct, because the recipient is not the same kind of party. And "we produced nothing, deliberately" is written down as an outcome, because an absent record cannot be told apart from a run that died.

On the desktop, a configuration that arms nothing is named as such, and refused. A profile that loads cleanly and matches nothing is reported as matching nothing and stops the send — and the verdict is computed by running the real loader over the real file, never by a second, more tolerant reader written for the report. Two readers of one format eventually disagree, and the one that disagrees quietly is the one in the report.

A backup that did not happen is a row saying so. The backup ledger records failures, and a restore is proved by drill rather than asserted — including reading the number of errors the restore ignored, because restore tooling exits successfully having skipped things. The drill has been run; it found six real defects before anybody needed it to work.

And support diagnostics are built from an allow-list, never a deny-list. A deny-list is a list of the secrets somebody thought of.

THE TEMPTING DEFAULT WHAT IS RECORDED INSTEAD A cost reading cannot be taken 0 unmetered Nought is a number. It sums correctly, it appears on a report, and it is wrong. An estimate needs a safety margin a multiplier somebody chose the p90 of this workflow's own past error, at this size Taken from the variance sample on every completed run. Quoting uses the raw estimate; only enforcement uses the padded one. A budget refuses a run “budget exceeded” the budget, what remains, of what, what was needed, and the multiplier A refusal nobody can act on is just an outage. And a budget that cannot price a run refuses it. A run needs to notify somebody the failure reason, in the email the run's name, and where to look A reason can carry an exception message, or name what a detector found inside the client's document. A mail server is covered by none of the decisions made about that material. A profile loads but matches nothing “loaded successfully” matches nothing — verdict from the real loader over the real file Never a second, more tolerant reader written for the report. Two readers of one format eventually disagree. A backup did not happen silence a row saying so, and a restore proved by drill Including the number of errors the restore ignored, because restore tooling exits successfully having skipped things. It records the cases where it could not decide, rather than recording a default and moving on. That is what makes every other decision on this page worth anything: a gap that is written down can be audited; a default cannot.
The tempting default, and what is recorded instead

Chapter 6

Interoperability is a dialect problem, not a format list

Every tool in this business claims to read the others' files. The list is the easy half. What decides whether your assets survive the move is narrower: memoQ and Trados write the same standard differently, and a system that reads both into one shape and writes one shape back has quietly changed your memories on the way through.

On the server, a dialect is a pair of pure functions — native to canonical, and canonical back to native — and they are inverses of one another, written and tested as a pair rather than as two converters that happen to exist. The incoming dialect is sniffed from the file, the outgoing one is yours to choose per export, and the pair carries a contract version that the client and the server pin together, so the two halves of one company's software cannot drift about what a <seg> means. Adding a dialect is a new adapter and a folder of fixtures, not a rewrite.

The desktop works differently. bAIbel AV opens and returns Trados and memoQ bilingual files, .sdlxliff and .mqxliff, keeping inline formatting, including formatting the translator added. What comes back is the work, not only the words: a segment the translator confirmed returns to Trados or memoQ as confirmed. One boundary travels with it: a project package is not a file it opens, so .sdlppx is not .sdlxliff.

File formats · Everything else

In closing

One position, two codebases

The two products share no runtime. They share rulings.

The word-count rule is CJK-aware and is the same rule in both, ported from the server to the desktop at the server's request, because two implementations of "how long is this document" produce two answers and one invoice. The formatting resolution described in §4 was built for the server and is shared from a common library. The doctrine that a PDF is converted rather than parsed was reached independently on both and turned out to be the same doctrine. And the rule that a person's approval takes a unit out of the partial-match band is pinned in both codebases at one commit.

That is deliberate, and it is the part that would be hardest to retrofit. Where a shared rule exists as two copies, it drifts, and the drift shows up as the two halves of one company's software quietly disagreeing about a client's document.

Regulatory surface — the regulatory surface, including what is not in place