Every software engineer has a system for their dev environment. Shell configs, dotfiles, editor plugins, CI pipelines. We spend absurd amounts of time optimizing the machinery around our code.
I built the same kind of system for learning English.
Not a casual “I should read more” plan. An actual system — with a daily routine, a phrase bank, logging infrastructure, feedback loops, and identified pain points I haven’t solved yet. The kind of thing where if you opened a PR on my English skills, you could trace the changes back to specific subsystems.
This isn’t about AI tools (I wrote about that elsewhere). It’s not about meeting prep specifically (that’s here). This is about the infrastructure. The daily ops. The system itself.
The 2-hour daily routine
Two hours a day. Sounds like a lot until you realize that’s less time than most engineers spend configuring Neovim plugins they’ll never use.
Here’s the breakdown:
| Time | Block | What happens | Why it matters |
|---|---|---|---|
| 30 min | Input + mimic | Listen to native speech with transcript, repeat after them | Can’t output what you’ve never input |
| 30 min | Shadowing | Shadow sentence patterns — real-time mimic while audio plays | Builds mouth muscle memory |
| 20 min | Phrase review | Review phrase bank entries tagged by context | Pareto principle — internalize the 20% that covers 80% |
| 20 min | Speaking | Speak out loud on a daily topic, record it | Spontaneous production, not just repetition |
| 20 min | Reflection log | Write what I wanted to say but couldn’t | Closes the feedback loop |
The order matters. Input before output. Listening before speaking. You wouldn’t deploy code without reading the docs first — same principle.
Why each block exists
Input + mimic (30 min): Speechify reads through material while I follow along with the transcript. Not passive listening — active mimic. I pause, repeat, try to match the rhythm. The material choice matters too: I pick personal growth or workplace communication content. Not TV show dialogue (too casual, too much slang) and not academic text (too stiff). The sweet spot is content that sounds like talking to a smart colleague — because that’s exactly the register I need at work.
Shadowing (30 min): This is the one that feels dumb and works the best. Play audio, shadow the speaker in real time, mouth moving along barely a beat behind. It’s how actors learn accents. The insight from my notes: read out loud for muscle — 读出声来是为了肌肉记忆. Your mouth literally needs reps, same as your hands need reps to type fast. Reading silently doesn’t train the muscles. Saying it out loud does.
I log each shadowing session: source, the sentence I practiced, how it felt, phrases to keep. Example from my log:
Source: YouTube (Speak English with Vanessa) Sentence: “I’m gonna head out, but let’s catch up soon.” Feeling: Natural, but tough linking between “gonna-head-out” Keep: “catch up soon”
Phrase review (20 min): This is the Pareto block. My notes have a key insight I keep coming back to: internalize 20% of phrases that cover 80% of scenarios (内化20%的表达覆盖80%的场景). Not vocabulary. Not grammar rules. Phrases — the actual chunks of language people use. More on this in the phrase bank section.
Speaking (20 min): Record myself talking about a topic. Send to Telegram. Get GPT feedback. This is the block I skip the most, and it’s the one that matters the most. The pain point is real: almost no spontaneous speaking practice happens unless I force it into the schedule.
Reflection log (20 min): The “wanted to say vs actually said” technique. This is where I write down the gap between intention and execution. More on this below — it’s the highest-signal thing in the whole system.
The phrase bank — Pareto for language
Most language courses teach you vocabulary. Words. Individual pieces. That’s like handing someone a bag of screws, brackets, and panels and saying “now build a shelf.”
What you actually need is phrases. Pre-assembled chunks. “Heads up” instead of “I” + “want” + “to” + “inform” + “you.” The chunk comes out as one unit — faster, more natural, less cognitive load.
My phrase bank is an Org-mode file with each phrase tagged by context:
** TODO [#B] I'm not sure how to explain it, but I'll try.
:USAGE: meeting, Q&A
:STATUS: new
:SOURCE: GPT / convo
** TODO [#C] I don't really know much about that, but I'd love to hear your take.
:USAGE: casual, when unsure
:STATUS: new
:SOURCE: ChatGPT
The tags matter. [meeting] phrases are different from [casual] phrases. “I’d love to hear your take” works at lunch with coworkers. It sounds weird in a sprint planning meeting. Context-tagging lets me review the right phrases before the right situations.
The status field tracks internalization. A phrase starts as new, moves to practicing, then fluent (at which point it drops off the review queue). Exactly like flashcard spaced repetition, but for full expressions instead of single words.
The Pareto insight again: I don’t need to know 10,000 phrases. I need to own maybe 200 that cover the situations I’m actually in. Meeting phrases, code review phrases, small talk phrases, “I don’t understand” phrases. That’s it. That’s the 20%.
The “wanted to say” log
This is the most useful tool in the entire system, and it’s embarrassingly simple.
Every day, I write down three things:
- What I wanted to say — the intent, in whatever language it comes in
- What I actually said — the mangled English that came out
- What I should have said — GPT’s suggestion for natural phrasing
Example from my log:
Wanted to say: “Can you explain that again in a simpler way?” Actually said: “Say again?” Better version: “Would you mind breaking that down a bit more?”
Another one:
Wanted to say: “What do you usually get here?” (at lunch with coworkers) Actually said: (nothing — froze, didn’t know how to say it casually) Better version: “What’s your go-to order?”
The gap between column 2 and column 3 is the most honest measure of where you are. Not a test score. Not a grammar quiz. The actual delta between what came out of your mouth and what you wished had come out.
Over time, column 2 starts looking more like column 3. That’s the compound interest. You don’t notice it day to day, but flip back a month and the gap has shrunk.
The technique also catches avoidance patterns. That second example — where I froze and said nothing — is the most important kind of entry. The sentences you don’t say are the ones that need the most practice. If you only log what you actually said, you miss the entire class of things you avoided saying because you didn’t have the words ready.
Tenses for progress reports — a cheat sheet
Here’s something weirdly practical that I dug out of my grammar notes. If you’re an ESL engineer, you give progress reports all the time — standups, syncs, 1:1s, Slack updates. And you probably use like two tenses for all of it.
Turns out there’s a distribution that covers almost everything:
| Tense | Usage share | When to use | Example |
|---|---|---|---|
| Present Simple | 25% | Routine facts, general truths | “Our team handles all client inquiries within 24 hours.” |
| Present Continuous | 25% | What you’re doing right now | “I’m working on the final stages of the update.” |
| Past Simple | 20% | Completed actions | “We completed the proposal last Friday.” |
| Present Perfect | 20% | Done, but relevant now | “We’ve received positive feedback this quarter.” |
| Future Simple | 10% | What’s coming next | “I’ll send the revised budget by tomorrow.” |
That’s five tenses covering ~100% of progress reporting. Present Perfect Continuous (“I have been working on…”) is maybe 5% — and honestly, you can just rephrase it as Present Continuous or Past Simple and nobody will notice.
The key insight: you don’t need to master 12 English tenses. You need to be fluent in five. For work contexts, those five cover everything. Prep your status updates by tense, and you’ll sound dramatically more polished.
Here’s how a status update maps:
“The batch migration is ready (present simple). I ’m working on (present continuous) the torch override for Linux CI. Last week I completed (past simple) the macOS smoke test. We ’ve unblocked (present perfect) 30 packages so far. I ’ll send (future simple) the migration plan by Friday.”
Five sentences. Five tenses. Covers past, present, and future. Your manager thinks you’re articulate. You’re just running a template.
The toolchain
Like any good engineering system, this one has too many tools and half of them are held together with duct tape.
Emacs + Org-mode: The phrase bank, speaking logs, shadowing logs, and daily journal all live in Org files. Everything links together. The phrase bank is reviewable with org-drill. The daily routine is a table I can clock in/out with org-clock. It’s overkill and I love it.
GPT (via gptel.el): Inline in Emacs. I paste what I said, it tells me what I should have said. No context switching. This is the feedback engine.
Speechify: Text-to-speech for the input block. Reads my study material at adjustable speed with a natural voice. I follow along with the transcript and mimic.
Telegram: Voice note recordings. I record my speaking practice and send it to myself. Sounds weird. Works great. The friction of recording keeps me honest — I can’t just think about what I’d say, I have to actually say it.
Browser extension + Python server + emacsclient: My phrase clipper. See a good phrase on the web, highlight it, it gets sent to a local Python server that calls emacsclient to write it into my Org phrase bank. The pipeline is: browser → Chrome extension → HTTP POST → Flask → emacsclient --eval → phrase bank. It’s janky. It works. Well — it worked. It lives on a different laptop and I’ve been too lazy to migrate it.
Google Calendar: Scheduling blocks for the daily routine. Without calendar blocks, the 2 hours “when I have time” becomes 0 hours every day.
What’s still broken
Every system has known bugs. Here are mine:
No daily habit yet. The 2-hour routine exists on paper. In practice, I do maybe 60% of it. Some days zero. The routine needs external forcing functions — calendar blocks, notifications, accountability. I haven’t built those yet.
Clipped phrases get dusty. The phrase bank grows but the review doesn’t happen consistently. Phrases go in and never come out. It’s like writing tests that never run. The infrastructure for capture is better than the infrastructure for retrieval.
Bad format on clipped phrases. The clipper grabs raw text without pronunciation guides, without native audio, without context tags. It captures what was said but not how to say it. The phrase bank needs a richer schema.
Not sure what the top 20% actually is. I keep saying “internalize the 20% that covers 80%” but I haven’t actually identified what that 20% is rigorously. Which 200 phrases would make the biggest impact? I should run frequency analysis on my own speaking logs and meeting transcripts to find out.
Almost no spontaneous speaking practice. The speaking block exists but it feels artificial. Real fluency comes from real conversations, not recording yourself talking to Telegram. I need a conversation partner or a practice group. This is the hardest infrastructure problem — you can’t automate another human.
The engineering approach to language
Here’s what I’ve learned from treating English learning like a software project:
Measure the gap, not the level. I don’t care about my “English level.” I care about the delta between what I wanted to say and what came out. That’s the metric. The speaking log is my test suite.
Optimize the hot path. I don’t need to be good at all English. I need to be good at work English — progress reports, code reviews, meeting back-and-forth, Slack messages. That’s the hot path. Everything else is nice-to-have.
Build for muscle memory, not knowledge. I know how to use present perfect. I can explain the rule. But in a meeting, my mouth defaults to past simple because that’s what the muscles remember. Shadowing is reps. Speaking practice is reps. Reading grammar rules is not reps.
减少数量, 增加质量 — reduce quantity, increase quality. Don’t try to learn 50 phrases a week. Learn 5, and own them. Say them out loud until they’re automatic. Quality of internalization beats breadth of exposure every time.
Ship incrementally. The system isn’t done. The phrase clipper is broken, the daily habit is inconsistent, the review queue is dusty. That’s fine. I shipped v0.1 and I’m iterating. The alternative — waiting until I have a perfect system before starting — means never starting.
The system works because it treats fluency as an engineering problem. Not a talent problem, not a motivation problem, not an exposure problem. A systems problem. Build the infrastructure, show up for the reps, measure the output, iterate on the weak points.
It’s not glamorous. Neither is CI. But both of them compound.