Field Notes

Lucid: engineering applied to auditing document clarity

How I turned ABNT NBR ISO 24495-1 recommendations into traceable checks, regression tests, and suggestions that keep the decision human.

September 05, 2026 · Mariana Castro

Working with public documents, I kept running into the same contradiction: a text could be formally available, legally correct, and still remain inaccessible to the very people who needed to act on it. It wasn't a lack of information. The information was there, but it demanded that the reader cross long sentences, abstractions, acronyms, cross-references, and structures that seemed written to keep them out. Lucid came out of the urge to turn that discomfort into an engineering question: could I point out, with reproducible evidence, exactly where a document gets in the way of understanding?

The problem

A public document nobody understands isn't just a style problem. It's an access problem. Public notices, contracts, expert reports, and privacy policies can hold all the necessary information and still keep it locked behind sentences that stall the reader.

The available tools tend to take one of two paths. Some rewrite the whole thing with a language model and hand back a new text without making it fully clear what changed or why. Others produce a generic score, such as "readability: 62", without showing which passage caused it or which criterion was applied.

A third option was missing: a tool that measures a document against a standard, locates each occurrence, and presents the evidence behind the finding.

The idea: an auditor before a rewriter

Lucid starts from auditing. It works from verifiable criteria of clarity and structure, and its main reference is ABNT NBR ISO 24495-1, the standard that sets out how to write so readers can find, understand, and use the information. With that, "the text is bad" stops being a loose opinion and becomes a bounded conclusion: a given passage triggered a specific criterion, tied to an identifiable recommendation in the standard.

The difference in stance is central. The system doesn't silently replace the document, nor does it present its interpretation as truth. It highlights the passage, explains the problem, ties the finding to the matching criterion, and preserves the writer's decision.

When there is a rewrite suggestion, it stays a traceable, reviewable proposal. The author can compare before and after, understand the rationale, and decide whether the change makes sense in that context. The pen stays human.

The engineering decision: a deterministic core

The auditing core is deterministic. There are 24 detectors, each responsible for watching a pattern that can make reading harder. When a detector fires, it:

  1. marks the exact passage;
  2. identifies the criterion that grounds the finding;
  3. explains why that pattern deserves attention;
  4. keeps the result reproducible for the same input and configuration.

This makes it possible to test, compare versions, and investigate regressions without depending on a different answer each run. The question stops being "what did the AI think?" and becomes "which rule ran, over which evidence, and with what result?".

Choosing a deterministic engine, though, didn't make the problem simple. It only made its difficulties more visible. A standard written to guide people doesn't arrive ready to be executed by software. Each recommendation has to be translated into observable conditions, without reducing an ambiguous language to a naive collection of regular expressions.

The hardest work was calibrating that translation. A pattern can be a problem in one sentence and perfectly legitimate in another. Passive voice, deontic modality, sentence length, and complex constructions all depend on context. So each detector had to be treated as a testable hypothesis: define the minimum evidence, map the exceptions, measure false positives, and freeze regressions whenever a real case revealed an inadequate interpretation.

The cost of determinism is that painstaking work. The benefit is being able to explain exactly why the system made each decision.

The line between proof and signal

Not everything that makes a document clear can be proven by a machine. Some patterns are measurable: the number of words in a sentence, the presence of certain constructions, or the density of difficult terms. Others require someone who knows the audience, the document's purpose, and the context in which the information will be used.

Lucid separates these two kinds of result. On one side is what the engine can demonstrate from observable evidence. On the other is what it merely signals for human review.

That distinction also lives in the architecture. Each check declares up front the nature of the evidence it produces and the level of conclusion it can offer. Tests prevent context-dependent checks from being silently promoted to objective findings. Beyond validating positive examples, the suite covers exceptions, edge cases, and regressions found as the engine evolved.

So "proof" and "signal" aren't just two labels in the interface. They represent different contracts inside the system. The tool has to make clear how far it can go on its own and where the judgment of whoever is reviewing the document begins.

Testing language is testing ambiguity

Much of Lucid's evolution happened when real examples contradicted rules that looked correct on paper. A detector could work across dozens of sentences and fail on exactly one caveat, one obligation expressed indirectly, or one construction whose interpretation shifted with context.

These cases weren't treated as disposable exceptions. They became regression tests. Today the project holds 2,503 automated tests across unit cases, linguistic examples, consolidated scenarios, and comparisons between engine versions.

That suite made it possible to evolve delicate rules without losing already-validated behaviors. It also turned linguistic decisions into inspectable ones: when a rule changes, you can see which cases still pass, which stopped passing, and what precision-or-coverage trade-off was accepted.

What I left behind and what I'd do differently

The first versions of Lucid treated some linguistic rules as if they were more objective than they really are. As the test corpus grew, it became clear that finding a grammatical structure isn't the same as proving a comprehension problem. A passive construction, for instance, can hide the agent of an action, but it can also be the right choice in a given context.

If I started again, I'd define the evidence taxonomy before implementing the detectors. That would cut rework and force each rule to answer, from the start, three questions:

  1. What can this rule observe?
  2. What can it conclude from that evidence?
  3. What still depends on human judgment?

The limit remains part of the product. Lucid can measure formal patterns, highlight passages, and offer traceable suggestions, but it doesn't decide on its own whether a document fully serves its communicative purpose. Clarity also depends on audience, context, prior knowledge, and real consequences. No single detector can close that analysis.

What this project taught me

Building Lucid wasn't just implementing text rules. It was turning a standard into an executable system without pretending that every recommendation can become a binary answer. That meant modeling evidence, making uncertainty explicit, creating regression criteria, and designing an interface that didn't hide the engine's limits.

The most important lesson was that reliability doesn't come from a tool asserting it is right. It comes from being able to inspect how the conclusion was produced, reproduce the result, and disagree with it using evidence.

See it running

Lucid running: the flagged passage and the cited clause of the standard, side by side.

Try Lucid with a document of your own, or follow a complete audit example. Each result shows the analyzed passage, the evidence found, its relation to the standard and, where applicable, a suggestion that stays under the writer's control.


Written by Mariana Castro, Full-Stack Developer & Tech Lead in Fortaleza, Brazil. I build tools that turn complex processes into legible, trustworthy and auditable systems.

GitHub · LinkedIn · marianacastro.dev