# Writing at 80% ASD-STE100

*I told my agents to write in the controlled English of aircraft maintenance manuals, then measured what changed in their replies.*

> On 2 October Andrej Karpathy suggested asking an LLM to explain things in ASD-STE100, the controlled language aerospace uses for maintenance manuals. I added it to my agent harness the same afternoon, softened to 80%, together with an ELI5 opener and a format ladder that prefers a diagram or a page over prose. Then I measured my own Claude Code transcripts. Sentence length barely moved, because Opus 5.5 and my September anti-slop rules had already done that work. Passive voice and progressive verbs dropped, and the format ladder changed far more than the language rules did: the share of replies that came with an HTML page went up about eight times.

Published: 2026-10-02 · Reading time: 7 min · Tags: agents, claude-code, writing, ai-slop, ste100, controlled-language, product-management
Canonical URL: https://huytieu.com/blog/writing-at-80-percent-ste100/
Author: Huy Tieu (huytieu.com)

---

<!-- slop-ok: this post quotes STE rewrite exhibits -->
<style>
:root{--st-ground:#ffffff;--st-ink:#111827;--st-soft:#334155;--st-muted:#64748b;--st-quiet:#94a3b8;--st-line:#e6e8ee;--st-strong:#cbd5e1;--st-accent:#c15f3c;--st-node:#d97757;--st-sans:Inter,ui-sans-serif,system-ui,sans-serif;--st-mono:"JetBrains Mono",ui-monospace,"SF Mono",Menlo,monospace}
:root[data-theme="dark"]{--st-ground:#171b22;--st-ink:#f1f5f9;--st-soft:#cbd5e1;--st-muted:#8b95a5;--st-quiet:#5b6472;--st-line:#262c36;--st-strong:#3a4250;--st-accent:#e0885f;--st-node:#e0885f}
.st{margin:40px 0;padding:22px 22px 16px;border:1px solid var(--st-line);background:var(--st-ground);color:var(--st-ink);box-shadow:0 1px 2px rgba(16,24,40,.04)}
.st figcaption{margin-top:18px;padding-top:12px;border-top:1px solid var(--st-line);font:500 9px/1.6 var(--st-mono);letter-spacing:.1em;text-transform:uppercase;color:var(--st-muted)}
.st__k{font:500 9px/1 var(--st-mono);letter-spacing:.12em;text-transform:uppercase;color:var(--st-quiet);margin-bottom:14px}
.st-tw{margin:28px auto;max-width:440px}
.st-tw img{width:100%;display:block;border:1px solid var(--st-line)}
.st-tw figcaption{margin-top:8px;font:400 10px/1.5 var(--st-mono);letter-spacing:.06em;text-transform:uppercase;color:var(--st-muted);text-align:center}
.st-pair{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.st-pane{border:1px solid var(--st-line);padding:14px}
.st-pane--after{border-color:var(--st-ink)}
.st-pane p{margin:0;font:400 14px/1.55 var(--st-sans);color:var(--st-soft)}
.st-pane .lbl{display:block;font:500 9px/1.3 var(--st-mono);letter-spacing:.1em;text-transform:uppercase;color:var(--st-quiet);margin-bottom:10px}
.st-pane mark{background:none;color:var(--st-accent);border-bottom:1px dashed var(--st-node)}
.st-pane .cnt{display:block;margin-top:10px;font:500 9px/1.3 var(--st-mono);letter-spacing:.08em;text-transform:uppercase;color:var(--st-muted)}
.st-bars{display:grid;gap:10px}
.st-bar{display:grid;grid-template-columns:150px 1fr 54px;gap:12px;align-items:center}
.st-bar__who{font:500 9px/1.35 var(--st-mono);letter-spacing:.08em;text-transform:uppercase;color:var(--st-muted)}
.st-bar__track{height:14px;border:1px solid var(--st-line);position:relative}
.st-bar__fill{position:absolute;left:0;top:0;bottom:0;background:var(--st-strong);transform-origin:left;animation:st-grow 1.4s ease-out both}
.st-bar--hi .st-bar__fill{background:var(--st-node)}
.st-bar__v{font:600 12px/1 var(--st-mono);text-align:right}
.st-bar--hi .st-bar__v{color:var(--st-accent)}
.st-bar:nth-child(2) .st-bar__fill{animation-delay:.2s}.st-bar:nth-child(3) .st-bar__fill{animation-delay:.4s}.st-bar:nth-child(4) .st-bar__fill{animation-delay:.6s}
@keyframes st-grow{from{transform:scaleX(0)}to{transform:scaleX(1)}}
.st-rail{display:grid;grid-template-columns:repeat(4,1fr);gap:0;position:relative;margin-top:6px}
.st-rail::before{content:"";position:absolute;left:12%;right:12%;top:15px;height:1px;background:var(--st-strong)}
.st-rung{position:relative;text-align:center;padding:0 6px}
.st-rung b{display:block;width:30px;height:30px;margin:0 auto 10px;border:1px solid var(--st-ink);background:var(--st-ground);font:600 11px/28px var(--st-mono);position:relative;z-index:1}
.st-rung--pt b{border-color:var(--st-accent);color:var(--st-accent)}
.st-rung span{display:block;font:520 13px/1.3 var(--st-sans)}
.st-rung small{display:block;margin-top:6px;font:400 10px/1.45 var(--st-mono);color:var(--st-muted)}
.st-rung--pt small{color:var(--st-accent)}
.st-rail i{position:absolute;top:12px;left:12%;width:7px;height:7px;border-radius:50%;background:var(--st-ink);animation:st-ride 6s ease-in-out infinite;z-index:2}
@keyframes st-ride{0%{left:12%;background:var(--st-ink)}45%{left:62%;background:var(--st-ink)}55%,80%{left:62%;background:var(--st-node)}100%{left:87%;opacity:0}}
@media (max-width:700px){.st-pair{grid-template-columns:1fr}.st-bar{grid-template-columns:96px 1fr 44px}.st-rail{grid-template-columns:1fr 1fr;row-gap:22px}.st-rail::before,.st-rail i{display:none}}
@media (prefers-reduced-motion:reduce){.st-bar__fill{animation:none}.st-rail i{display:none}}
</style>

On 2 October Andrej Karpathy posted a thread of tips for reading model output. The first one was about writing. Ask the model to explain things in ASD-STE100.

<figure class="st-tw"><a href="https://x.com/karpathy/status/2105819303471976479"><img src="/assets/ste100/karpathy-ste100.jpg" alt="Andrej Karpathy's post: ask your LLM to explain something in ASD-STE100, a controlled language specification" loading="lazy"></a><figcaption>Andrej Karpathy, 2 Oct 2026</figcaption></figure>

I had never heard of it. [ASD-STE100](https://www.asd-ste100.org/) is Simplified Technical English, the controlled language the aerospace industry uses for maintenance manuals. It exists because the mechanic who reads a torque procedure at 3 a.m. may not read English as a first language, and a misread instruction can take down an aircraft. So the spec limits what a sentence can do. An instruction has 20 words at most and one action. A description has 25 words at most. A paragraph has six sentences. Each approved word has one meaning, and you use that word every time.

Karpathy said he found the output more readable than the model's default prose. He also said "80% of the way", because the full spec is strict enough to hurt. That softening is what made me try it. I had spent September fighting slop in my agents' writing ([the em dash post](/blog/ai-slop-after-the-em-dash/) is the long version), and every rule I had was a ban on a pattern. STE was the first thing I had seen that describes the target instead of the failures.

## What I added

I wrote it into the [no-ai-slop](/blog/ai-slop-after-the-em-dash/) skill that every agent in my vault loads, and into my global `CLAUDE.md`, the same afternoon. The commit landed at 14:02 Saigon time. The rules that carry over at 80%:

- Instructions: 20 words max, one instruction each, verb first.
- Descriptions: 25 words max. Paragraphs: six sentences max.
- Active voice, unless the actor is unknown.
- Simple tenses. "The job is running" becomes "the job runs".
- One term per meaning. If the doc calls it a "run", it never becomes an "execution" two paragraphs later.
- Noun clusters of three words max.
- Keep the articles. A terse model drops "the" and "a" to save tokens, and the text gets shorter and slower to read.
- In a warning, the command comes first and the reason second.

The 20% I left out: technical terms and product names stay as they are, my own voice wins when an agent edits something I wrote, and hedges stay when the uncertainty is real. This post is in my voice, so it breaks the 25-word limit in a few places.

The noun-cluster rule is the one I feel most when I read agent output about my own product. Test management software is a factory for stacked nouns.

<figure class="st" role="img" aria-label="The same status sentence before and after the STE rules. The noun clusters in the first version become short sentences with verbs in the second">
<div class="st__k">One status sentence, rewritten (illustrative)</div>
<div class="st-pair">
<div class="st-pane"><span class="lbl">Default</span><p>The <mark>test run report export button</mark> was being shown to users without the <mark>project analytics view permission</mark>, which was causing confusion during <mark>sprint review preparation workflows</mark>.</p><span class="cnt">1 sentence · 27 words · 3 stacked clusters</span></div>
<div class="st-pane st-pane--after"><span class="lbl">80% STE</span><p>Users without permission to view project analytics saw the button that exports the test run report. This confused people who prepared the sprint review.</p><span class="cnt">2 sentences · 13 + 9 words · active voice</span></div>
</div>
<figcaption>The rewrite is five words shorter, and the reader no longer has to unstack five nouns to find out what the button does.</figcaption>
</figure>

Two more rules came from the same thread, and I added them in the same commit. An explanation for someone who did not build the thing opens with an ELI5 paragraph: three sentences, everyday words, one analogy. And when the goal is understanding, prose is the lowest rung of a ladder. A diagram beats prose, an HTML page beats a diagram, and an explainer video beats a page, as far as the medium allows. Code is cheap now, so a page that exists to explain one thing and then gets thrown away is a fine thing to build.

## What changed in the transcripts

I like to check whether a rule did anything. Claude Code keeps every session as a JSONL transcript, so I wrote a small script (`ste-compare.py`, in my vault next to the [model comparison script](/blog/fable-opus-5-opus-5-5-on-my-own-work/)) that takes every text block the lead agent wrote, strips code and quotes, and splits the prose into sentences. Bullets, table rows and headings count as fragments and do not count toward sentence length. It compares Opus 5.5 in the ten days before the commit with Opus 5.5 in the days after. The after window is only five days old, so read every number below as early.

The first result surprised me. Sentence length barely moved.

<figure class="st" role="img" aria-label="Share of prose sentences over 25 words: Fable 5.1 in early September 13.3 percent, Opus 5 15.6 percent, Opus 5.5 before STE 4.7 percent, Opus 5.5 after STE 4.1 percent">
<div class="st__k">Sentences over 25 words, lead-agent chat replies</div>
<div class="st-bars">
<div class="st-bar"><span class="st-bar__who">Fable 5.1 · Sep 1-21</span><span class="st-bar__track"><span class="st-bar__fill" style="width:85%"></span></span><span class="st-bar__v">13.3%</span></div>
<div class="st-bar"><span class="st-bar__who">Opus 5 · Sep 1-21</span><span class="st-bar__track"><span class="st-bar__fill" style="width:100%"></span></span><span class="st-bar__v">15.6%</span></div>
<div class="st-bar st-bar--hi"><span class="st-bar__who">Opus 5.5 · before STE</span><span class="st-bar__track"><span class="st-bar__fill" style="width:30%"></span></span><span class="st-bar__v">4.7%</span></div>
<div class="st-bar"><span class="st-bar__who">Opus 5.5 · after STE</span><span class="st-bar__track"><span class="st-bar__fill" style="width:26%"></span></span><span class="st-bar__v">4.1%</span></div>
</div>
<figcaption>The big drop happened before STE, between Opus 5 and Opus 5.5 under my September rules. STE moved the last bar by 0.6 points.</figcaption>
</figure>

Mean sentence length went from 12.8 words to 12.3. The median went from 12 to 11. Under Opus 5 and Fable 5.1 in early September, about one sentence in seven ran past 25 words. Under Opus 5.5 it was already one in twenty-one before I wrote a word of STE into the harness. Paragraphs over six sentences were already at zero. The length limits in STE describe a place my agents had already reached through a newer model and a month of bans.

The grammar rules did show up. Sentences with a passive verb fell from 9.2% to 7.6%. Progressive verbs ("is running", "was failing") fell from 2.6% to 1.8%. Those are small numbers on a small window, but they move the way the rule says, and they are the kind of change that a length check cannot catch. My passive regex is crude, so I trust the direction more than the size.

One number went the wrong way. Replies got longer, from 76 words per text block to 98. Some of that is the ELI5 paragraph, which adds three sentences to the front of every explanation. Some of it is probably what I asked for in those five days. I do not have a way to separate the two yet.

## The format ladder did more

The rule that changed my week was the ladder, and it took one line of grep to see it. In the ten days before the commit, my lead agent published 19 HTML artifacts across 1,409 text replies. In the five days after, it published 52 across 479. That is 1.3% of replies before and 10.9% after, about eight times as often.

<figure class="st" role="img" aria-label="The output format ladder: STE prose, diagram, HTML page, explainer video. The HTML page rung is highlighted, with artifact use rising from 1.3 to 10.9 percent of replies">
<div class="st__k">Output format ladder, highest rung the medium supports</div>
<div class="st-rail">
<i></i>
<div class="st-rung"><b>1</b><span>STE prose</span><small>Slack, email, Jira, commits</small></div>
<div class="st-rung"><b>2</b><span>Diagram</span><small>flows, sequences, state</small></div>
<div class="st-rung st-rung--pt"><b>3</b><span>HTML page</span><small>1.3% → 10.9% of replies</small></div>
<div class="st-rung"><b>4</b><span>Explainer video</span><small>a mechanism to watch</small></div>
</div>
<figcaption>Rung three moved the most. The agent now answers "explain this roadmap" with a page I can click through, and the chat reply becomes a sentence and a link.</figcaption>
</figure>

I can feel the difference more than I can measure it. This week a question about our standalone runner roadmap came back as a page with a timeline I could scroll, and the reply in chat was a sentence and a link. A month ago the same question got paragraphs. The ELI5 opener counts for less in the numbers (the grep found it in six replies), but when it appears it is the part I read first.

Part of this is the model. Opus 5.5 reaches for tools more than any model before it, and I wrote about that [last month](/blog/fable-opus-5-opus-5-5-on-my-own-work/). The ladder gave it permission to reach for one specific tool, and it took the permission right away.

## What I would tell someone starting

If your agents still write long, nested sentences, the STE length limits will help, and "write this in 80% ASD-STE100" is a short enough instruction to paste anywhere. Models know the spec. You do not need to explain it.

If your agents already write short sentences, the length rules will not move much, and the value is in the parts a ban list cannot express: active voice, one term per meaning, warnings that lead with the command. Those describe good writing directly, which is easier for a model to aim at than a list of things to avoid.

And try the ladder. I expected the language rules to be the main change and the ladder to be a footnote. Five days in, it is the other way around. I will rerun the script at the end of October with a full month on each side and see whether either result holds.
