A teammate posted a doc in our Slack channel. “Test taxonomy for the yolo monorepo.” Two pages, a big table, some definitions. The kind of document that should take five minutes to read.
I stared at it for twenty.
And I couldn’t tell if the doc was bad, or if my English was bad.
The feeling
This is the specific hell of being an ESL engineer reading internal docs. Every unclear sentence triggers a two-way investigation: is the writing ambiguous, or am I parsing it wrong? Native speakers get to skip that step. They read something confusing and think “this is poorly written.” I read something confusing and think “maybe I don’t know the word ‘cadence’ well enough.”
Spoiler: I know what cadence means. The doc was confusing.
But it took me twenty minutes to arrive at that conclusion with confidence. Twenty minutes of re-reading the same paragraph, switching between English and Chinese mental models, looking up words I already knew just to make sure. That’s the tax.
What the doc says
The taxonomy classifies tests into four types based on isolation and infrastructure:
| Type | Isolation | Infra | GPU |
|---|---|---|---|
| Type 1 | Full (hermetic, no external deps) | Standard CI runners | No |
| Type 2-cpu | Partial (may need services) | Team-managed CI | No |
| Type 2-gpu | Partial (may need services) | Team-managed CI | Yes |
| Type 3 | None (real cluster, real data) | Cluster access | Yes |
There’s also a matrix of who “owns” what, when tests run, and what triggers them. The doc presents all of this as settled fact — here are the types, here are the columns, done.
And that’s where the problems start.
Angle 1: The taxonomy is ambiguous
The table headers sound clean — “Type”, “Owner”, “Infra”, “GPU” — but they collapse multiple dimensions into single words.
“Owner” means three different things. Who runs the tests? Who triages failures? Who provides the test framework? These are three separate org-chart questions, and the doc jams them into “Own” and “Support” columns without defining which meaning applies where. DevEx “supports” Type 2 — does that mean we maintain the CI pipeline? Provide the test runner? Debug failures? All three?
Type 2-cpu and Type 2-gpu aren’t subtypes. They’re called subtypes in the doc, but they have completely different infrastructure ownership models. One runs on standard CI runners, the other requires GPU-enabled runners with a separate provisioning pipeline. That’s not a subtype — that’s a different type wearing a trenchcoat.
Type 3 says “no isolation guarantees” but requires cluster access. That IS an isolation requirement. You can’t run it on a random machine — you need a specific cluster with specific credentials. “No isolation” actually means “different isolation model that we haven’t clearly defined.”
Trigger and cadence are nearly identical across types. Every type triggers on PR and runs on merge. So why is it a distinguishing characteristic in the taxonomy? If a column has the same value in every row, it’s not a classification axis — it’s a constant.
Angle 2: Where did this taxonomy come from?
The doc presents four types as given facts. No derivation. No methodology. No evidence.
Questions I had that the doc doesn’t answer:
- Was this from observation? Did someone audit the test suite and discover these clusters? If so, show the audit.
- Was this from interviews? Did teams describe how they think about tests? If so, who was interviewed?
- Was this from vibes? One person’s mental model, written as universal truth? Possible. Common. Bad.
- What percentage of tests fall into each type? If Type 1 covers 80% of tests and Type 3 covers 2%, that changes the entire priority structure. The doc doesn’t say.
- Are there real examples? Not “a Type 2 test might look like…” but actual test names from the monorepo mapped to each category.
test_data_forge_pipelineis a Type 1.test_gpu_training_e2eis a Type 2-gpu. Show me.
Without evidence, the taxonomy is one person’s mental model. Mental models are great — they’re just not documents. A document needs to show its work.
Angle 3: The language problem
This is the ESL-specific angle, and it’s the one I almost didn’t write about because it feels like complaining.
It’s not complaining. It’s a design problem.
Jargon without definitions. The doc uses terms like “hermetic,” “isolation guarantees,” and “test cadence” without defining them. For native speakers, these are probably obvious from context. For me, “hermetic” sent me on a three-minute detour confirming it means “fully self-contained, no external dependencies” and not something about temperature sealing.
Mixed abstraction levels. One paragraph will discuss org chart ownership (who triages), then jump to test properties (isolation level), then jump to CI configuration (runner type). Three layers of abstraction in five sentences. My brain processes English in a more serial way than native speakers — I can’t context-switch between layers as fast, so I keep losing the thread.
Ambiguous pronouns. “It requires GPU access and they manage the infrastructure for it.” What’s “it”? The test? The type? The runner? Who’s “they”? DevEx? The team that owns the test? The sentence is grammatically fine — a native speaker resolves these instantly from context. I have to re-read the previous three sentences to figure out what “it” refers to.
Table headers that need the whole doc. You can’t understand what “Infra” means in the table without reading the surrounding paragraphs. For a scanning-first reader (me, ADHD) who goes straight to the table, the headers are meaningless without context.
None of these are ESL-only problems. Native speakers would also benefit from clearer definitions and consistent abstraction. But for ESL readers, each one of these issues doesn’t just slow you down — it makes you doubt whether you’re understanding the doc at all.
The written feedback
Here’s what I’d post as a PR comment or Slack reply. Clean, structured, direct. The version I can draft in advance, edit three times, and feel confident about.
Overall: I think the taxonomy captures something real, but the doc needs more structure before it’s useful as a shared reference. Three areas:
1. Clarify what the columns mean.
- “Own” and “Support” mix three concepts: who runs tests, who triages failures, and who maintains the framework. Can we split these?
- “Infra” is ambiguous — does it mean “what kind of runner” or “who provisions the runner”?
2. Show the derivation.
- How were these four types identified? Observation? Interviews? If we added a “Methodology” section, it would help readers trust the categories.
- Can we include 2-3 real test examples from the monorepo for each type?
- What percentage of our tests fall into each type?
3. The Type 2 split needs rethinking.
- Type 2-cpu and 2-gpu have different infra ownership models. Calling them subtypes implies they share more than they do. Are these actually separate types?
Minor: the trigger/cadence columns have nearly identical values across all types. Should we either differentiate them or remove them from the classification?
That took me about forty minutes to write. Not because the ideas are hard — I had them within ten minutes of reading the doc. But because translating “this is confusing and I think the categories are wrong” into diplomatic, structured, clear English is a separate skill from having the technical insight.
Writing is the easy one. I get to revise. I get to look up words. I get to restructure sentences until they sound like someone who thinks in English.
Speaking is harder.
The meeting version
Same feedback. Out loud. In real time. With a human staring at me waiting for my response.
Here’s what that actually sounds like.
Scene: weekly DevEx sync. The doc author (ALEX) has just finished a 3-minute summary of the test taxonomy. The team lead (RYAN) opens it up for feedback. Five people on the call.
RYAN: Alright, thoughts? Anyone have feedback on the taxonomy?
(beat — three seconds of silence that feels like thirty)
ZOE: Yeah, I have some— I had some questions when I was reading it.
(gathering thoughts — the English sentence is forming but the ordering isn’t there yet)
ZOE: So, the columns in the table. “Own” and “Support” — I wasn’t sure what they mean exactly. Like, is “own” the team that runs the test, or the team that triages when it fails, or the team that builds the framework? Because those could be different teams.
ALEX: It’s the team responsible for the test. Like, if it fails, they fix it.
ZOE: Okay, so that’s triage ownership. But then the “Support” column — is that the team that provides the infra? Like, DevEx provides the CI runners?
ALEX: Yeah, basically.
ZOE: I think it would help to make that explicit in the doc. Because right now “own” and “support” could mean a few different things.
(internal thought: okay that landed fine, next point is harder)
ZOE: The other thing— um, Type 2-cpu and Type 2-gpu. The doc calls them subtypes, but they have pretty different… uh…
(searching for “infrastructure ownership model” but the phrase won’t form fast enough)
ZOE: …pretty different setups? Like, 2-cpu is on normal CI runners, and 2-gpu needs GPU runners with a whole different provisioning pipeline. That feels more like different types than subtypes.
ALEX: I see them as subtypes because the isolation level is the same — they both have partial isolation. The GPU part is just an additional characteristic.
(pushback — need to respond in real time, can’t pre-draft)
ZOE: Yeah, the isolation level is the same, but the infra ownership is completely different. And for DevEx, the infra part is what actually matters for our work. So maybe… uh…
(if thought is forming:)
ZOE: Maybe the taxonomy should have a separate axis for infra complexity instead of folding it into the type number.
(if thought is NOT forming:)
ZOE: I’m not sure what the right structure is, but I think calling them subtypes undersells the difference. Can I put some thoughts in the doc async?
RYAN: That’s a good point. Alex, what do you think?
ALEX: I could see splitting them out. Let me think about it.
ZOE: One more thing — and this might just be me — but I couldn’t tell from the doc how the types were decided. Like, was this from looking at the actual test suite, or more of a conceptual framework?
(this is the hardest feedback to give out loud — it implies the author didn’t do rigorous work)
ALEX: It’s based on my experience working with the tests. I looked at what we have and tried to categorize them.
ZOE: Okay, that makes sense. I think if we add some real examples — like, “test_data_forge is a Type 1, test_gpu_e2e is a Type 2-gpu” — it would make the categories more concrete. And maybe we could add a rough count of how many tests fall into each type?
ALEX: Yeah, I can do that.
(internal relief — the hard feedback landed without conflict)
RYAN: Great, let’s move on. Zoe, can you add your comments to the doc so Alex can reference them?
ZOE: Yeah, I’ll add them today.
What you don’t see
Here’s what was happening in my head during that three-minute exchange:
The three-second pause at the beginning — that wasn’t me being thoughtful. That was my brain switching from listening-mode English to speaking-mode English. Different cognitive processes. Native speakers switch instantly. I need a beat to load the output module.
“I had some questions” is a rehearsed opener. I have about five of these pre-loaded for meetings: “I have a question about…”, “I wasn’t sure about…”, “Can you clarify…”. They buy me three seconds of speaking time while my brain assembles the actual content.
“pretty different… uh… setups?” — I wanted to say “infrastructure ownership models” but the phrase wasn’t available in real-time. “Setups” is the fallback. It’s less precise, but it communicates. You take the word you can reach, not the word you want.
“and this might just be me” — this is a hedge I use specifically because I’m never 100% sure if the confusion is the doc or my English. It’s also a softener for feedback that might sound like “your doc is bad.” Both functions at once.
“Can I put some thoughts in the doc async?” — escape hatch. When I can feel the real-time English generation hitting its limit, I punt to writing. Writing is safe. I can edit. I can think at Chinese speed and output at English quality.
The order of feedback changed. In my written version, I led with columns, then derivation, then the Type 2 split. In the meeting, I led with columns (easiest to articulate), then Type 2 split (medium), and saved the derivation question for last (hardest — it implies the author didn’t do enough work). I reordered by cognitive difficulty, not logical importance.
The two skills
Giving technical feedback in writing and giving it in a meeting are fundamentally different skills. For native speakers, the gap is small — you might be more polished in writing, more casual in speech, but the core ability transfers.
For ESL speakers, the gap is enormous.
Written feedback is an editing problem. You have the technical insight. You have the diplomatic framing. You just need to map both into clean English, and you can take as long as you need. It’s open-book. It’s async. It’s safe.
Spoken feedback is a generation problem. Same technical insight, same diplomatic framing, but now you have to produce English in real time, under social pressure, while also reading the room for reactions, while also planning your next sentence, while also maintaining the thread of a multi-person conversation. It’s a juggling act where one of the balls is on fire and the fire is in a foreign language.
The written version took me forty minutes. The meeting version takes three minutes. And the meeting version is ten times harder.
What I’m practicing
I script meetings now. Not the whole thing — just the hard parts. The feedback I know I need to give, the questions I know will come up, the two or three moments where real-time English generation is most likely to fail.
It’s like an actor rehearsing lines. The script doesn’t survive contact with reality — the other person says something unexpected, the conversation branches — but having a starting structure means I’m generating from a template instead of from scratch.
The written feedback I posted above? That was also my meeting prep. I wrote it, then read it out loud three times, then practiced responding to imaginary pushback. The “infrastructure ownership model” phrase that I couldn’t reach in the meeting? It was in my written version. If I’d rehearsed one more time, maybe it would’ve been available when I needed it.
Or maybe not. That’s the thing about real-time language — you can practice, but you can’t guarantee. The buffer between your brain and your mouth has a limited bandwidth, and English takes more bandwidth than Chinese. Some days the pipe is wide. Some days it’s narrow. You don’t get to choose.
The doc is still bad, though
Just to be clear: the taxonomy doc has real problems. Ambiguous columns, no evidence for the categories, subtypes that aren’t subtypes. Those aren’t ESL complaints — those are engineering complaints.
But the ESL layer means it took me twice as long to identify the problems, twice as long to articulate them in writing, and ten times as long to articulate them out loud. The cognitive cost isn’t just the English — it’s the constant uncertainty about whether the difficulty is the language or the content.
Every ESL engineer in tech carries this tax. Most of us don’t talk about it, because talking about it requires the same English fluency we’re struggling with.
Which is, if you think about it, kind of perfectly annoying.