Text-First

If It Can Be Text, It Should Be Text

Short on time? Jump to the worked example.

Disclaimer: You can find a small ToDo API example here, built end-to-end using what I describe below. Don’t worry, this is not yet another SDD framework. Actually, it’s a methodology, a “non-framework framework”. I’m mentioning the repo up front because methodologies without code samples deserve skepticism.

Everybody is Talking About AI, Not Everybody is Happy

By now, everybody has read at least one “AI is going to replace you!!1! (Or not?)” article. Or is writing one right now. This is not one of them. I have opinions on that question, but they’re not what this piece is about. What I want to get at is something else: why is AI-assisted development so polarizing? Why can two engineers, same model, same tools, end up with such wildly different results?

I was a skeptic at first. “Blockchain all over again,” I’d mutter, smirking at the code quality of this ChatGPT thing — considering myself oh so superior and not seeing the point of copying code back and forth into a browser window like a soulless robot. Boy, was I naive. That was two years ago. My doubts have mostly been dispelled since, and my confidence in AI-assisted development keeps rising. The people around me, though, are still split into two camps: AI prophets and AI skeptics.

The prophets claim to be using AI for everything. They claim to not have written a single line of code without AI for at least a year. And they are constantly running dozens of agents in parallel. Each in its own git worktree, of course. They claim that 10x is not a myth - they are living proof.

On the other hand, I have participants in my workshops telling me: “AI is not for me. Played with it, didn’t like it, I am just here because my boss wants me to be.” There’s another group that outright works against AI, trying to make it fail with an evil grin of Schadenfreude. If you dig deeper, you will find that ultimately, they fear replacement. Finally, there are many people who are open-minded but still quit out of frustration. AI seems smart in their opinion, but it’s never doing what they want it to do.

I get the frustration. For months now, Claude Code has been the “tool du jour” and it feels like you’re doomed if you don’t use it. Or worse, you must be stupid if you are not succeeding with any of the hyped tools or models, when clearly so many of the vibe-coding prophets do.

It all reads like you only need to use the right tool and suddenly everything will be smooth sailing. In my opinion: it really doesn’t matter that much. With today’s tools and models, you can get good results consistently, if you provide the right context. It’s about how you use the tools, not which tools you use. Who would have thought?

The 70% Problem

“They (=LLMs) can get 70% of the way there surprisingly quickly, but that final 30% becomes an exercise in diminishing returns.”
-Addy Osmani

I think Addy Osmani nailed it with this statement. It’s what decides between a positive and a negative experience with AI-assisted development. If you close the remaining 30% gap quickly, you’ll have a good time. And this is not just subjective personal experience - it’s also efficient from a business perspective. What does ‘economically viable’ actually mean here?

Productivity = Domain Expertise x AI Leverage - Rework

Productivity will increase proportionally to the domain expertise of the user and the boost they can get from using AI tooling. But it’s the last part, “Rework”, that decides whether the whole exercise will be worth it. My claim:

AI becomes economically viable when the last 30% becomes cheaper.
It’s not the generation that’s expensive - it’s the rework.

Garbage In, Garbage Out

So, how can we close that gap? How can we make the last 30% cheaper? The answer is: by providing better context. Sounds obvious, but reality proves that it’s not. Relevant context is often missing, incomplete, scattered across tickets, Slack, PDFs, PowerPoints, Confluence pages nobody maintains or locked away in the heads of colleagues long gone.

It’s a common misconception that we just need to “sit this out” and wait until context windows are big enough to include the entire codebase. But there’s evidence that more context is not always better. In fact - and I consider this quite human - if you give an LLM too much context, it will get overwhelmed and not know what to do with it or start to hallucinate. Same as me. Context needs to be precise, and that won’t change.

Not enough contextToo much contextJust the right context
Model starts to guess and fills gaps with plausible assumptionsIrrelevant tokens will clog the context windowBespoke context as guardrails for the response

The hard truth is that every single imprecision, contradiction, or missing piece of information in the prompt context will ultimately be punished and lead to more rework. Context Engineering will stay relevant and it will be a crucial skill for developers to master for the foreseeable future.

So how do we provide meaningful context? Not once, but continuously, without repeating ourselves?

Spoiler: It’s not about prompt voodoo or finding the perfect tool. It’s about the oldest technology humanity has ever invented.

Language is Everything

The greatest invention of humanity is not the wheel. It’s language. I think in language, I even dream in language. As a developer, I am building with language. If you look at past disruptions in software development, they all had to do with language. AI is no exception, it’s the logical next step.

EraEvolution
1940smachine code (0/1)
1950sassembler
1970sC, ASCII
1990shigh-level languages, HTTP, HTML
2000sMarkdown, JSON, YAML
2020snatural language → AI-assisted development

Each step in this evolution brought us closer to using natural language as the primary interface for programming. For the first time in history, we can communicate as equals with our tools. Text has become the interface that both human and machine understand perfectly.

Markdown is Text++

If you ever took down notes on your computer, you probably used a plain text file. Why? Because it’s painless. Easy to create, easy to edit, and easy to share. Chances are, if you did this more than once, you probably invented your own “formatting” system to provide more structure to your plain text notes. Whatever it was, my bet is that it is not that far from Markdown. Because that’s all that Markdown is, really: just a standardized way to add structure to plain text. If you read the seminal article, the arguments still hold true today.

Markdown is Everywhere

Since then, Markdown has slowly but steadily transformed from a nerdy markup language into the Esperanto of the AI era. It is used everywhere: from READMEs, wikis, issues and pull requests on GitHub or GitLab, to documentation in Notion, Obsidian, Confluence, and even Google Docs. It’s the default for static site generators, from Jekyll to Astro. It’s not a coincidence, it’s a trend. And it’s not just a community thing, the trend is noticeable in the enterprise as well. When even Microsoft is embracing Markdown - a company that has been notoriously resistant to open formats - you know it’s a big deal.

I’m not the only one to make the observation that Markdown is taking the world by storm. Here, here and here, other people are noticing the same thing.

Why Markdown? Why now? Well, it certainly does have its advantages:

  • Simple - you can learn it in 10 minutes, even if you’re non-technical
  • Readable - even without tools, yes, you can even view it in Notepad
  • Diffable - ever tried diffing Word documents in Git?
  • Structured - headings, lists, code, tables, links, images, …
  • Open - no vendor, no format lock-in, it’s free and open source
  • Future-proof - no company behind it, no risk of it being discontinued

But let’s not kid ourselves, the real reason is AI. Markdown has become the lingua franca of LLM workflows. Not .pdf, not .docx or .vsdx, not .html or even .txt - Markdown. Readable enough for humans, structured enough for machines.

I’m not trying to hide the fact that Markdown is not without criticism. In fact, it has been criticized as long as it has been praised.

But my personal belief is that Markdown is quite similar to passwords in that regard: just too damn convenient to get rid of.

The Lie

Let’s make a short detour to talk about documentation. Why documentation, you ask? Bear with me, it’ll all come together in a bit.

Who hasn’t heard the phrase “Our code is self-documenting”? Or, my personal favorite, “Code is Documentation”? No. Code is code. Code can only show the “what”, never the “why”. But that is what you typically want to know after a couple of years: why do we still have this message bus? What does it actually do? Why did we rewrite our core backend service in Rust again? It’s hard to answer these questions by only reading code. Let’s face it: we’ve been lying to ourselves for decades. Because real documentation has just always been too expensive.

Documentation and tests have always been duking it out for the honor of being cut first when deadlines or budgets get tight.

If documentation exists at all, it’s often a mess of outdated Confluence pages, half-hearted READMEs, PDFs and Visio diagrams, random notes in Slack. It’s too far away from the code to be useful for the people who actually need it. There have been attempts to keep documentation as code, but while well-intentioned, they often fail because developers still don’t find the time to write or maintain the docs.

Every Team has a Sarah

This is a structural problem that everybody is too afraid to admit. That message bus I was talking about above? You know who knows why it’s there? Sarah. Sarah is the only one who was around back in the day when it was implemented, and she is the only one left who understands it. Most of all, Sarah knows why that damn message bus is still there, even though it seems to be doing nothing. The problem? Sarah quit in 2024. And now, we are stuck with that message bus and nobody dares touch it.

Why Documentation Failed

OK, got it, writing documentation is hard. But you know what is even harder? Maintaining documentation. Even if you are willing to invest the initial effort, after a few iterations, other priorities will always be more important than updating the docs.

And that’s when documentation silently starts to lie and become a liability instead of an asset. It’s a vicious cycle that acknowledges the importance of documentation, yet allows only one half-hearted conclusion: “Code is Documentation”. Or rather: “Code must be Documentation”. Because real documentation has just always been too expensive.

The (new) Token Economy

So why am I talking about language and documentation again? What does that have to do with AI? Glad you asked.

With AI, documentation has finally become affordable

Instead of spending hours writing and maintaining documentation, or worse - giving up on it entirely - we can now use AI to generate and maintain documentation for us. What used to take half a day for the initial draft and ended up at 2-3 days of total work after iterations can now be done in minutes. Every change that took at least half an hour to document is now just a few minutes and one prompt away. For the first time ever, creating and maintaining documentation is economically viable.

AI Makes Us Write Documentation Anyway

Enter AI. With AI, writing documentation has become mandatory. We need to write prompts and provide context. If we don’t - and we already saw this - LLMs will punish us with more rework. So why not make a virtue out of necessity and write documentation for AI in a way that benefits us humans, too? If done right, we can kill two birds with one stone: We can provide better context for AI and at the same time create documentation that is actually useful for humans. I hear someone say “Win-Win” in the back rows.

Documentation becomes a byproduct of AI-assisted development instead of a luxury:

Same text, two audiences.

There is No Such Thing as Free Tokens

Earlier this year, the cost of heavy AI use became harder to ignore. The carefree flat-rate plans that many users relied on in the past began to disappear and were replaced by token-based allowances and paid overages. With a shift away from carefree usage, you suddenly had to pay attention to spending your tokens wisely. While recently token prices for the latest models started getting cheaper again, premium models and long-context usage can still carry substantial costs. We saw providers struggling to keep their offerings profitable, and there have been stricter rate limits, and even some providers restricting access to certain models or pausing new subscriptions altogether.

This does not come as a surprise, however. We as developers have shifted from mere chatting towards agentic workflows, burning through tokens faster than you can say “OpenClaw”. GitHub explicitly attributed its restrictions to long-running, parallel agent sessions consuming more resources than its original plans were designed to support. It’s clear that this poses a challenge for providers, and until someone presents a viable fusion reactor, we can expect efficient token usage to stay relevant for the foreseeable future.

If we have to use AI more efficiently, what does that mean for us as developers? One question that I hear frequently in my seminars and workshops is: “How can I estimate the number of tokens a task will consume?” The answer is disappointing: you can’t. There is no reliable way to predict overall token usage with precision. You can get pretty accurate estimates for input counts before sending a request, but what we cannot know precisely is the consumption of the entire task. You never know how much additional context the agent will read, how much output it will generate, and how many extra laps a model must take to arrive at an answer; and that answer might even be wrong. You could try to develop an intuition for similar tasks over time, but consumption still varies substantially between runs.

What you can (and should!) do is

  • Budget your tasks. Model-facing task budgets can help pace the work (if supported), but hard limits have to be enforced on top: max_tokens caps each request, and the tool running the agent has to cap the task as a whole.
  • Account for repeated context and caching. Cached context typically comes at a significant discount.
  • Load context selectively. Minimize unnecessary token consumption by pre-selecting only the most relevant context, providing it in a concise form that preserves the relevant constraints.

Nothing Beats Text

We already established that succeeding with AI means providing optimal context. So the question of token efficiency is really the question of how to provide optimal context in the most efficient way. The answer is:

If it can be text, it should be text.

Text is the primary interface between human and model. Preserve images only where the visual information matters. But when the information is already textual, feeding the model with anything but text means actively working against its strengths.

Take office formats or PDFs, for example. Sure, you can feed them to the model, but if the assignment focuses on their textual content it will require extracting the text anyway. Any format but text will ultimately pay a conversion tax, as these formats require extra processing and can introduce additional token overhead. There are converters (remember MarkItDown?) and tools that allow you to convert the heavy formats, but that’s just glossing over the symptoms, not eliminating the problem.

I hear people say “Just wait, in a few years, we’ll only be talking to AI, the years of typing are over.” Not so sure about that. Apart from the awkwardness of “speaking CSS”, audio or even video will always be less efficient than text in terms of information density. I’ll have to ask: Why would we keep wasting tokens by providing the model with formats it will turn into text in the end anyway?

And I think this is the real reason why Markdown has become AI’s native tongue:

As a format that is understood by both human and machine, Markdown’s simplicity, information density and token efficiency is unbeatable.

But What About HTML?

You may have seen Anthropic’s article being passed around as a proposal to replace Markdown with HTML. Read it more carefully - that’s not quite their claim. They, too, talk about information density. However, their listed use cases include scenarios where the artifact’s consumption benefits from HTML and CSS. So things like design prototypes, interactive specs or report templates - basically anything that is primarily authored by the LLM and consumed via rendering. HTML outputs can be useful for rich, rendered artifacts, no doubt.

What they are not talking about is the shared-memory layer we care about here. And sure, HTML offers even more flexibility than Markdown, but it comes at a price. HTML means more ceremony. It may be quick to read and edit for the LLM, but much less so for us humans. It’s not a coincidence that Markdown - not HTML - has become the go-to format for documentation and communication in the software industry.

Markdown’s simplicity and efficiency make it the preferred choice when operating on the shared-memory layer. Try it yourself: compare the experience of collaborating with the LLM on a Mermaid diagram in a fenced Markdown block vs. a hand-rolled SVG in HTML. The latter is just not enjoyable, and much slower. The Mermaid output is almost always good enough for the task. The added flexibility of HTML is outweighed by the cognitive load of its syntax and CSS quirks in particular. HTML and CSS simply start to get in the way. Rapid iteration and collaboration mandate a lightweight format, and Markdown seems to be the sweet spot.

Prompt Customization - The Win-Win-Win Scenario

You might already see where this is going. But let’s first recap why prompt customization files have been such a game changer and what the situation was before we had them.

The Memento Connection

LLMs are stateless per se. They have no memory between requests, no way of keeping track of previous interactions. What feels like “session state” to us is actually maintained by the client. It resends the entire conversation with every prompt and once the conversation context approaches the model’s context window limit, you either have to start cutting off the beginning of the conversation, start a new one or compact (i.e. summarize) what was said so far. Remember the movie Memento? I always picture LLMs with Guy Pearce’s face.

Before Prompt Customization: Groundhog Day

This had direct consequences for how we used LLMs. If you wanted to have a conversation with the model, you had to send all the necessary context with every new conversation. All conventions, best practices and guardrails had to be retold. Every single time. No wonder experiences with AI-assisted development varied wildly.

Prompt Customization: Deceptively Simple Magic

Who would want to type all that? No one did. But people can be creative. So they started to save recurring prompts in files, and copy-pasted them into prompts when needed. With more and more people adopting and promoting this approach, we saw LLM providers offering more and more support for this pattern:

ToolPurpose
AGENTS.mdGlobal context, added to each prompt. Contains conventions, best practices and guardrails.
Custom AgentsUser-defined agents with specific behaviors and capabilities.
SkillsReusable, composable, and shareable. Can be invoked on-demand.

And while they all seem like magic and suddenly make our models “smart”, if you look at them closely, it’s almost embarrassing how simple they are: just Markdown files with some conventions. Subagents, plugins, even MCP: all just variants of the same principle. In the end, they end up as additional context for the model. Even hooks can be used to inject textual context at specific points in the agent lifecycle. Ever wondered about the miracle of memory features and how they made the model suddenly remember things? This is essentially the same principle: shared memory, persisted across sessions and fed back in as context. Guy Pearce’s Polaroids, if you will.

Prompt Customization = Standardized Conventions

The Eye Opener

While blatantly obvious in hindsight, it took a while for me to realize this. I wouldn’t have to wait for providers to support these features in the tools I use, I could just add them myself. It’s not as convenient as clicking on a mode button, but I could have had plan mode long before it was rolled out as a feature. Just write a Markdown file telling the model what it means to be planning out some task. Add this to your prompt, and voilà, you have a “planning agent”. Here’s an example for a custom agent doing just that.

Win-Win, again

Remember the win-win scenario from above? Same text, two audiences? Prompt customization files are the perfect example of that. If we approach them smartly, we can turn them into actual documentation that is not only useful for the model, but for us as humans as well. Think about it this way:

What you are telling the model in these files is also what you would want to tell a new team member.

So why not write them in a way that lets them serve both purposes? With a little effort, they can be the shared memory of the project. The place where conventions, best practices and guardrails are documented and maintained.

For AIFor Humans
Context, without repetitionOnboarding documentation
Rules, conventions, best practicesArchitecture & stack overview
Examples from own codeConventions, shared in writing
Clean separation of prompt and contextLess typing, less rework

Finally, Win-Win-Win

If we follow this approach, our Markdown prompt customization files can become the single source of truth for both human and machine. They serve three purposes at the same time:

  1. Context for AI
  2. Documentation for humans
  3. Prompt customization (i.e. automated standardization)

And all that without any additional effort.

Prompt Customization is no longer optional - it is the new Status Quo.

The Sum of All Parts

Programming with AI is programming with Markdown, whether we like it or not. Looking at all the pieces we’ve discussed so far, I had an epiphany.

Cascading Eurekas

  • AI needs context. Durable. And token-efficient.
  • Token-efficient means: Markdown.
  • Durable means: Git.
  • Versioned in Git, the Markdown automatically becomes documentation for humans.
  • In the right place, the Markdown becomes prompt customization at the same time.
  • One file. Three purposes. No extra effort. Just text.

Markdown

Git

Documentation

Prompt Customization

Context for AI

Text-First: If it can be text, it should be text.

Isn’t This Just SDD?

Hold on, you say, isn’t this the same thing spec-kit, Kiro or GSD Core (the former gsd) are doing? And much more sophisticated, too? Isn’t this yet another SDD framework?

Similarities

And you’re right - Text-First and SDD do share some similarities:

  • Spec as Single Source of Truth
  • Architecture & planning before coding
  • Specs as guardrails to reduce variance
  • Built-in verification steps

Differences

First things first: I’m all for spec-driven development. What I’m wary of is the framework layer on top. Text-First avoids the worst downsides of SDD frameworks. I’m not comfortable with the abstraction lock-in, nor with adding another black box layer on top of the AI. Having two layers of “magic” will make debugging so much harder, because you never know whether it’s the LLM causing trouble right now or some contradictory statements in one of your spec files. Text-First is SDD with the tools you already have.

I don’t think I suffer from an old-man-yells-at-cloud strain of “Not Invented Here” syndrome, not yet anyway. It’s more a reality check after having worked in the industry for more than two decades and having smelled scorched earth just a few times too many. I do think twice these days before committing to the latest hyped-up framework. Don’t get me wrong, I am not against using frameworks, libraries or tools. I just want them used and picked wisely.

Why I Prefer Text-First

Do we really need yet another framework?

I’m not trying to claim I’ve found the hidden manual of AI-assisted programming. I’m not trying to sell you a framework or product. I just want to give you something simple that works for me, reliably and consistently.

Where SDD frameworks:

  • produce lots of spec text to review and keep in sync
  • come with their own tooling, sometimes with their own IDE
  • spend a lot of tokens on ceremony
  • are often overkill for the problem at hand

Text-First on the other hand is:

  • still spec-driven, but with few files, and only when needed
  • not a tool, not a framework, requires no downloads
  • works with any model and any agent, no integration needed
  • token-efficient, loads only the context a task needs
  • flexible enough to start small and expand when needed
  • complete with what SDD pipelines tend to skip: refactoring and doc gardening
  • quick to adopt new built-ins: when hooks came along, they slotted right in

The fact that Kiro has introduced Quick Spec and GSD Core now has /gsd-quick suggests that users want lighter, more flexible approaches within the SDD ecosystem.

If Vibe Coding is the SVN Workflow of AI-assisted development and SDD is its GitFlow, then Text-First is its GitHub Flow.

Text-First in Practice

Time to get concrete. As promised, there is nothing to install and no tooling to learn - Text-First is a set of conventions, it’s explicitly not a framework. It’s not a religion either, its rules are deliberately loose - feel free to adapt them as you see fit. Let’s start with something almost trivial, yet somehow often overlooked when working with AI-assisted development.

Commit the Conversation

The discussion you’re having with the AI is based on Markdown. You can either copy it as Markdown directly, or - if your tool doesn’t support it - you can ask the AI to output it as Markdown for you. And while you’re at it, you can also ask it to summarize, reorder, or highlight key points. This conversation contains the “why”, the alternatives you considered and rejected, the “how”. In other words: exactly those valuable pieces of information we said code can never express. The information that walked out the door with Sarah. But it’s right there, sitting in your terminal or your chat window, ready to be preserved. So let’s preserve it:

Copy. Paste. Commit.

That’s the whole recipe. Here’s what a simple conversation dump can look like. Note that this is already distilled, not a raw dump:

# doc/api-discussion.md

> What endpoints does a simple ToDo API need?

CRUD is enough for the MVP:

- GET /todos
- GET /todos/{id}
- POST /todos
- PUT /todos/{id}
- DELETE /todos/{id}

> Do we need filters like ?completed=true?

Not for the MVP. They can be added later without a breaking change.

> What about status codes?

200, 201, 204, 400, 404. No generic wrappers in the body.

Conversation turned documentation, versioned in the repo and serving as persistent context for the next session. Documentation becomes a byproduct instead of a chore, an audit trail in Git - dated with every commit - and a whole lot less typing next time. Making AI understand again why we do things this way is a simple click instead of telling the same story over and over again.

“Stop right there!!1!”, you might say, “this is nothing new. It’s just ADRs, but worse because there’s no structure to it!” And you’re absolutely right. I actually do recommend using ADRs, e.g. with a light-weight Markdown template. But I deliberately wanted to avoid templates here. Because I want to stress the fact that it’s not mandatory. Text-First works without any ceremony, with no templates to fill in, no reformatting, no extra tools.

The conversation dump is the ADR you get for free.

Preserving the conversation is what ultimately matters most. The model understands its own output instantly in the next session. Of course, some housekeeping will pay off tremendously in the long run, but it’s not a requirement to get started. If you prefer something more structured, you may even have AI turn your conversation into proper and well-formatted ADRs. That would be a great use case for an agent skill. Too lazy to write it? Ask the model to write it for you. Or just use one of the many that already exist.

Set the Documentation Free

There’s a corollary to the above that deserves to be spelled out: documentation must live close to the code - otherwise it serves neither human nor AI. Remember the sad inventory from the beginning? Knowledge scattered across tickets, Slack threads or formats that are hard to edit or even locate, such as PDFs, Visio diagrams or - my personal favorite - blurry photos of whiteboards that nobody is able to decipher anymore? None of this is accessible to the model, and let’s be honest, barely to any of us either.

This was never ideal, but it is outright disastrous in the age of AI. A human reads a rotten Confluence page with skepticism and discounts it. An LLM ingests it as ground truth and confidently builds on the lie. Garbage context isn’t just unhelpful - it’s amplified. The same is true for committed Markdown, of course, but the difference is that, for the first time, we have someone to do the gardening. Have the AI distill before you commit, prune notes that newer decisions supersede, and fold doc cleanup into the Refactor phase of Text-First. Treat doc changes as part of the code review, where a wrong assumption gets caught before it spreads.

The docs-as-code folks had the right instinct all along - it was just not economically viable. But it is now. With conversations landing in the repo as simple text, with AGENTS.md and skills living next to the source, and with the AI shouldering the maintenance, documentation may finally live there where it provides the most value.

The key insight to succeeding with documentation in this new paradigm is:

Instead of doing the work yourself, use AI to generate documentation for AI. It doesn’t get more meta than that.

“But My Boss Wants PDF!”

Whenever I present this approach, this objection comes up reliably within minutes. And it’s a fair one: some stakeholders will never open an editor, let alone a Git repository. They want their PDFs and PowerPoints, no way to convince them otherwise. No problem, the solution is simple:

Markdown is the source, not the target.

Nothing about Text-First demands that Markdown has to be the final delivery format. Non-technical stakeholders will keep receiving their PDFs and PowerPoints - generated from the Markdown sources at the push of a button, using tools such as Pandoc, md-to-pdf or Marp. The deliverables become disposable artifacts, regenerated on demand, while the single source of truth stays in Git: versioned, diffable, reviewable.

Write once, publish anywhere.

The Six Phases of Text-First

The conventions above already get you a long way, but they really come into their own once you follow a structured workflow. I typically split any non-trivial feature into six phases, three to come up with a plan and three to build it:

next iteration

Coding & Maintenance

Error

4 Implement

5 Test

6 Refactor

Planning & Design

1 Discuss

2 Design

3 Plan

Again, don’t take this as dogma. Feel free to skip a phase when the task at hand doesn’t need it. The point is to have a clear structure you reach for when it helps, not a process you obey blindly. And before anyone asks: no, this is not waterfall in disguise. Waterfall ran through its phases once per project, over months, and found out what went wrong at the very end. A Text-First cycle covers a single feature, takes hours, and loops right back to the start.

So… This Is Plan Mode, Right?

Isn’t this just an overengineered way of using the plan mode that most agentic tools offer these days? No. It’s more than that. True, plan mode is an integral part of the workflow. But with Text-First, there is an artifact for each phase. With plan mode alone, you would just get the plan itself and many don’t even bother saving it (you absolutely should).

The artifacts of each phase are the context for the next phase, acting as guardrails that guide the work and ensure consistency. Best of all, nothing is written twice: the discussion becomes the design, the design becomes the plan, the plan becomes the code, and the tests and refactorings become the feedback loop that keeps the implementation on track.

PhaseArtifactsWhat you gain
Discussconversation notes, open questionsrequirements become visible
Designconversation, Mermaid, API docsdecisions become durable
Planimplementation planwork becomes reviewable, resumable
Implementcode + updated docsthe implementation follows the plan
Testunit and integration teststhe AI gets feedback
Refactorcleaned-up code, pruned & synced docsthe result stays maintainable

Every phase leaves a trail that persists context as documentation. If somebody needs to read it (again), or if you need it as context for a different prompt, it’s already there. Apart from the artifacts themselves, structuring the conversation with AI in this manner is also a great example of Generated Knowledge Prompting and Prompt Chaining.

Text-First in Action

It’s time to see Text-First in action. Let me walk you through it with the ToDo API from the demo repo. Try it out yourself: check out the bare-repo branch, run the prompts and compare the result with the implementation branch.

Phase 0: Laying Down the Permanent Context

Before the first phase begins, it pays to write down the general rules - the context that doesn’t change from task to task.

The bare minimum you should consider is an AGENTS.md. Think of it as the briefing you’d give any new team member on their first day: the stack you’re on, the conventions you expect, the guardrails you don’t want crossed - it’s a written “how we do things around here”. Without it, every session starts from zero (remember our agent, Guy Pearce?). But once you have it, the knowledge it contains is implicit and persistent: the model reads it before every task, and you never need to type it again:

# AGENTS.md — ToDo API (abridged)

## Tech Stack

- Spring Boot 4, Java 25, Gradle 9
- JUnit 6 + Mockito + RestTestClient
- …

## Conventions

- Boxed `Boolean` in DTOs (not primitive `boolean`)
- Do not add a database, repository layer, Docker setup or authentication unless explicitly
  requested
- …

## Required Reading Before Any Task

- doc/api-endpoints.md
- doc/todo-class-diagram.md
- …

Read it as a human and it’s an onboarding doc. Hand it to the model and it’s a system prompt. Same text, maintained in exactly one spot.

AGENTS.md covers the always-true. For anything more involved - a multi-step workflow you keep repeating, with its own rules, templates and examples - reach for a skill. Where AGENTS.md is loaded on every prompt, a skill is task-specific context, pulled in only on demand when the model decides a specific skill is applicable based on the task at hand. It’s the difference between “this is how we work in general” and “this is precisely how we do X around here.”

Capturing such a workflow as text becomes mandatory once AI enters the picture - there’s simply no other way to inform the model of its existence. That’s why I’ve heard people call prompt customization files “AI files”. Don’t fall into that trap.

These files matter at least as much to your human colleagues as to the AI. Writing a workflow down means every contributor, human or AI, does it the same way, and the procedure itself becomes documentation. Had Sarah written down her knowledge and skills (pun intended), Jack could simply have picked them up after she left.

The demo repo has a skill for adding new endpoints. The documentation part is the real killer feature here: instead of repeating yourself over and over again (“update docs”, “update docs”, said the parrot) or worse, writing the docs yourself, the model does it for you. Even when you forget to ask it (and you will), the skill acts as a guardrail and reminds the model without your active intervention. But since skill activation is probabilistic, you can make it required reading in AGENTS.md and apply an enforcement hook if a workflow is mandatory. The result is a single source of truth for the workflow and for the documentation alike.

None of this is special tooling. It’s still the same shared-memory Markdown idea we’ve been talking about all along, just placed where the tooling picks it up automatically. It really is worth repeating, but with an important addition:

Prompt Customization is automation and documentation of conventions and best practices.

Start with AGENTS.md, add skills when a workflow earns one, and grow the rest only when a real need shows up.

Phase 1: Discuss

With the permanent context in place, work on the actual feature starts with a conversation, not with code. In the Discuss phase, the AI is your sparring partner: brainstorm the feature, weigh alternatives, make technology choices, let it poke holes in your assumptions. This is deliberately the cheapest moment of the whole workflow - no code exists yet, so changing your mind costs nothing. The goal is to make the requirements visible, including the ones you didn’t know you had.

Don’t fall for the common mistake of thinking that as long as you are “just prompting”, you could save a few tokens by using a cheaper model for the “talking”. It’s quite the opposite: the Discuss-Design-Plan phases are where you invest in correctness and alignment, which pays off exponentially during implementation. If you have to use cheaper models for saving tokens at some point, the Implement phase is where you can afford to do so: it’s easier to follow a well-laid plan than to come up with one. That’s why we software architects get paid the big bucks, remember?

For the ToDo API, the opening prompt is almost embarrassingly simple:

What endpoints should a simple ToDo API provide?

Notice what happens here: the answer is already on rails. The model has read AGENTS.md before you typed a single word, so its proposal follows your stack and your conventions instead of some generic tutorial’s. The permanent context is doing the heavy lifting, silently. Without it, there would be no guardrails to steer the model, increasing the variance of the output.

One practical tip: stay in the same session for the Discuss-Design-Plan phases. Each answer builds on the previous one - that’s the Generated Knowledge Prompting pattern from earlier, applied naturally. And when the discussion settles, you know the drill by now: Copy. Paste. Commit. The conversation dump from the beginning - doc/api-discussion.md with its questions and answers - is exactly this phase’s artifact (the repo contains the raw, undistilled version). The “why” is preserved before it evaporates with the session.

Phase 2: Design

Design is where teams traditionally reach for Visio or some UML tool. Don’t. Draw your diagrams as code instead: Mermaid inside a fenced Markdown block. Versioned in Git, diffable like any other text, rendered natively by GitHub and GitLab, and - this is the important part - readable and writable by the model itself. That last property enables something I like to call design ping-pong: the AI proposes, you object, it revises, you add your own ideas, the AI challenges them. It’s almost like the good old times in front of a whiteboard. Without the social awkwardness. Each iteration takes seconds instead of an afternoon getting - these - fricking - connector - lines - to - look - nice. Focus on ideas instead of fighting the tools.

How does this look in practice? Continuing in the same session:

Propose a Mermaid class diagram for a simple ToDo resource served by the ToDo API.

The first proposal might contain attributes you didn’t ask for - and, LLMs being non-deterministic, different ones every time. Fine - that’s why we play ping-pong:

Leave createdAt and updatedAt out for now.

A round or two later, you’ve converged on the model you actually want:

Todo

+Long id

+String title

+String description

+Boolean completed

Pure text. Reproducible, maintainable, diffable. Note that in the demo repo the model got it right on the first try. It also followed the Boolean convention we laid out in AGENTS.md and wrote down why: “Using Boolean lets request validation distinguish an omitted completed field from an explicit false.” That’s exactly the kind of “why” the conversation dump preserves.

Once the proposal looks right, persist it. Either you do it manually, or you let the agent handle it:

- Add the Mermaid diagram to `doc/todo-class-diagram.md`.
- Add the API endpoints you proposed above to `doc/api-endpoints.md`.

With that, the decisions have become durable. These two files are now the authoritative contract: the blueprint for the plan that follows and the reference for every future change - which is why they’re on the required-reading list in AGENTS.md.

Phase 3: Plan

The Plan phase exists to prevent the classic failure mode of AI-assisted development: impulsive one-shot coding. “Build me X. Make no mistakes” produces plausible-looking code within seconds - along with guessed requirements, hallucinated APIs and no common thread to follow. That’s the 70% trap in its purest form: fast generation, expensive rework. Plan-first inverts this. The model reads the repository, does its own research, asks clarifying questions, and produces a step-by-step plan that you review and approve before a single line of code is written.

Most agentic tools ship a plan mode these days, and you should absolutely use it. But remember the eye opener from earlier: it’s not magic, just text. If your tool doesn’t have one, a Markdown file describing what planning means gets you the same behavior.

Here’s the entire planning prompt for the ToDo API:

Plan the initial implementation of the ToDo API.

One line. The prompt names the task and nothing else, because the repository does the explaining: AGENTS.md, the API contract, the class diagram - it’s all already there. This is the payoff of the previous phases, made visible. You can see this reflected in the plan - almost everything in there is derived from these files:

## Implementation Steps (Excerpt)

1. **Confirm and align docs first**
   - Treat `doc/api-endpoints.md` and `doc/todo-class-diagram.md` as the contract.
   - Add `doc/curl-examples.md`, since it is required but currently missing.
   - Expand `README.md` with prerequisites, start/test commands, and the endpoint overview.

...

## Assumptions

- Implement exactly the CRUD surface already listed in `doc/api-endpoints.md`.
- No database, repository layer, Docker, auth, pagination, filtering, or PATCH endpoint.
- Missing `completed` means `false` for create and update.
- Error response bodies may use Spring’s standard readable error representation; tests should assert
  required status codes and only assert body details where the contract specifies them.

Review the plan like you would review a pull request. This is the last cheap point to catch a misunderstanding: it costs one edited sentence here, and an afternoon of rework two phases later. Then commit it, e.g. as doc/implementation-plan.md. The plan is documentation for humans and, just as importantly, an anchor for the machine: if the session dies halfway through implementation, the next one reads the plan and resumes at step 4 instead of starting from zero. For this to work reliably, add “Use - [ ] checkboxes and tick them off as you go” to the planning prompt. The demo run omits this because the implementation was expected to be a single pass.

This is the natural point where you can afford to create a fresh session. Everything that the model needs to know is in the plan and the documentation artifacts already created. Research even backs this up: models make more mistakes when their own earlier errors are still in the context. A fresh session starts without that baggage.

This is again very Memento-esque: the committed plan and documentation are the Polaroids mentioned earlier. The new session wakes up with no memory, reads them, and knows exactly what to do next.

Phase 4: Implement

Now - and only now - comes the code. And precisely because everything that matters has already been said in the artifacts, there’s almost nothing left to prompt:

Start implementation.

That’s not laziness, it’s the whole point. The plan drives the implementation, not the prompt. What remains is a clear division of labor:

The AIYou
Pair programmer with full contextMonitor the process
Works through the plan, step by stepLet the model self-validate each step (more on that later).
Review the result - never rubber-stamp it.
Asks when something is ambiguousGive feedback on plan and code
Documents deviations from the planWhen something’s off: fix the plan, not the code

The rule in the bottom-right corner is the one I want to highlight: fix the plan, not the code. When the implementation goes sideways, the temptation is to patch the generated code directly. But then the truth lives in the code again and the artifacts have started to lie - and we know from the Sarah story how that ends. Adjust the plan or the design doc, then let the implementation follow. The artifacts stay authoritative, and the correction itself becomes documented context for the next session.

If you feel the need to make changes directly in the code yourself, remember to also update the plan and the documentation artifacts accordingly. You don’t need to do this manually. The agent can handle it for you, ensuring consistency across all artifacts - but you need to be aware of it and request the updates explicitly.

It’s tempting, but please, never wave changes through. Review, understand, learn. The moment you stop understanding your own codebase, you’ve traded the 30% rework problem for a 100% ownership problem.

Phase 5: Test

Without tests, the AI is poking around in the dark. It’s like writing code on a whiteboard: it may look good, but you won’t know until you try to actually run it. Tests are meant to provide that feedback.

In the demo repo, this phase needs no prompt of its own - and that’s by design. AGENTS.md declares tests mandatory, and the create-test skill teaches the model how to write them properly. Spring Boot 4 was too new to be well-represented in training data when I created the repo - the skill turns trial-and-error into one-shot success by supplying the model with Spring Boot 4 conventions on the fly. So testing simply happens during implementation, as a guardrail doing its silent work.

This is the inner loop in Text-First: write, run, read the failures, fix, rinse & repeat. Recent models are comfortable (and competent) running it on their own and it’s the biggest quality lever once coding starts: the model catches its own mistakes while they’re still cheap.

Step out of the loop and onto it: no babysitting every red test, no relaying stack traces. Your place is at its boundaries: you define what “done” means before it starts (the plan, the tests that have to pass), and you review what comes out. That’s no contradiction to “never rubber-stamp”. A green test suite only proves that the code does what the model understood. Whether it understood correctly is still your own judgment.

One more reason why tests deserve a dedicated phase: they are living documentation - executable examples of how the API is meant to behave, which makes them context in their own right. Existing tests teach the model how to write the next ones, so your testing style propagates automatically.

Tests are the obvious feedback source, but not the only one. The model will use anything that tells it whether it got something wrong: the compiler, type checkers, linters, formatters, static analysis. Don’t leave it to chance whether it does. Name the checks in your prompt customization files, and where it really matters, enforce them with hooks or CI. In the AI era, good engineering habits pay off twice: every automated check tightens the guardrails and takes another bite out of rework.

Phase 6: Refactor

The most skipped phase - and that was true long before AI. With AI, skipping it becomes expensive, because current LLMs are not great at grasping the big picture. Over the course of a larger task they drift: similar code accumulates in three places, a convention is honored here and quietly ignored there. Not because the model is bad, but because it never sees the whole board at once. You do. That’s why Refactor is essential to the workflow, not just a nice-to-have.

The prompts can stay as simple as ever:

Do you see any potential for refactoring? Please explain your reasoning and list the findings in order of importance.

(Side note: Yes, I do say “please”, despite all the advice not to. Be polite, and Skynet might spare you, too.)

The AI proposes - you decide. Same principle as in the Implement phase: you are the one with the bigger picture, so the judgment calls are yours. For the mechanical parts - renames, extractions, moves - prefer your IDE’s deterministic refactoring tools where possible. They’re guaranteed behavior-preserving and cost exactly zero tokens.

And this is also where the promised doc gardening happens: prune notes that newer decisions have superseded, sync the documentation with what was actually built, add new invariants as they turn up. Codebase and shared memory get maintained in the same breath: this is the only way the shared memory stays trustworthy.

Here’s a simple prompt to take care of doc gardening:

Compare `doc/` with the implementation. List anything outdated, contradictory, or superseded.

Text-First and Loop Engineering

You’ve just watched Text-First go through a full cycle: plan, build, check, refactor, and back to the start. That’s a loop - and loops are what everybody’s talking about right now. Many see us writing loops in the future. It is an emerging idea that has also arrived in the enterprise. Is this hype? Loop Engineering is the new Context Engineering is the new Prompt Engineering? My personal opinion is no. I believe our entire profession is in the process of leveling up in the same way we did when stepping up from awkward copying & pasting code from browser chats towards agentic engineering. This seems to be the logical next step in the still young discipline of AI-assisted software development.

We have been taught to treat code generated by AI with suspicion - trust but verify. And with good reason: if we let current models run for too long without oversight, drift seems inevitable. The likely reason: errors tend to compound. Now Loop Engineering comes along and asks you to challenge and reconsider the role of human oversight in the development process.

If we demand to have the last word on everything, we are destined to become the eternal bottleneck, slowing down progress at every step. We are turning into that micromanaging team lead who envies the new hire everyone keeps raving about, putting as many spokes in their wheel as we possibly can. We even do it for the same reason as said team lead: if we’re not doing it, we fear being replaced by the new hire. Don’t be that guy. Loop Engineering dares you to ask “what if?” and let go - design the loop and then trust it.

Don’t take this the wrong way: this is explicitly not Claude Code in YOLO mode. Loop Engineering is not asking you to be reckless or to drink coffee all the time until the agent is done with whatever it was doing the entire day. What it is asking you is to step back and let AI take the lead. It is addressing the elephant in the room: with recent models as powerful as they are, why would we still presume to take the lead in tasks where AI clearly outranks us?

How I Stopped Worrying and Learned to Love the Loop

Our role is shifting away from being the ones writing the code towards being architects and orchestrators ensuring that the thing writing the code has the ideal context, guidance, and constraints to produce high-quality results: we are designing the loop, we are loop engineers now. Remember the one-line “Start implementation.” from the Implement phase? The plan did the prompting, not you.

As Peter Steinberger of OpenClaw fame puts it: “You should be designing loops that prompt your agents.” Remember “use AI to generate documentation for AI”? Same idea: the AI writes the artifacts that end up prompting it.

Folks, it hurts me to say it, but: code is no longer where we express intent. It’s still what we ship, own and have to understand - but the ground truth for what it should do has moved one floor up. The specification has taken over the pole position.

This shouldn’t come as a surprise, though. If you look again at the programming evolution table from the beginning, this has always been the end goal: using language to create software. What we are witnessing now is just another step on that ladder. There’s no point mourning the way we did things back in the good old days. I’ve made my peace with it, and you should, too.

It’s not like we haven’t been through this dilemma of giving up control before, or are you really still checking the byte code of your compiled classes manually every time? I hear you saying “But compilers are deterministic and LLMs aren’t.” Which is exactly why the tests and the review stay. Think about it: the programming language you are using today is already an abstraction over the machine code, just like Text-First and Loop Engineering are abstractions over the code itself.

Don’t be sad. I was at first, I’ll admit it. But I’ve come to embrace it. A Loop Engineer is still a coder at heart. You still get to be a hacker, there are still plenty of opportunities for showing off how smart we are - no need to feel nostalgic. Welcome to the future of coding.

Loop Engineering is still coding, only it’s coding with words.

Are Prompt Engineering and Context Engineering Dead Now?

Addy Osmani’s article on Loop Engineering cites Boris Cherny, head of Claude Code at Anthropic, saying “I don’t prompt Claude anymore. I have loops running that prompt Claude and figuring out what to do. My job is to write loops.”

Don’t read this as “you don’t need to write prompts anymore”. You still do. Just not as often. And not exclusively in a chat window or CLI anymore. The text you write in your prompt customization files is, at the end of the day, just as much a prompt by another name. Prompt Engineering patterns still matter when it comes to crafting effective prompt customization files. Case in point: Discuss-Design-Plan is Generated Knowledge Prompting in action.

The same is true for Context Engineering. It is not obsolete either. IBM even lists it as a component of Loop Engineering. I know, recent models have become pretty good at searching and finding relevant context on their own. But forcing them to do so comes at a price: the whole searching for clues consumes time and tokens. You’ll be better off providing bespoke context upfront whenever possible.

Human-in-the-Loop, Human-on-the-Loop, Human-out-of-the-Loop ?!?

If you follow the discussions around Loop Engineering, you will eventually come across the terms Human-in-the-Loop (HITL), Human-on-the-Loop (HOTL), and Human-out-of-the-Loop (HOOTL). They describe different levels of AI autonomy and the corresponding involvement of humans.

HITLHOTLHOOTL
Human approves every critical stepHuman monitors and can interveneHuman not involved in the loop
Example: AI drafts an email — human approves before sendingExample: AI runs nightly tests — human monitors and stops if neededExample: AI spell-checks and autocorrects your writing in real time
Good for: High-risk tasks where human judgment is crucial and mistakes are costlyGood for: Low to medium-risk tasks where AI is superior and human monitoring is sufficientGood for: Low-risk tasks where speed and autonomy are prioritized over human oversight, mistakes are tolerated
Trade-off: Maximum control, but slow due to human approvalTrade-off: Faster due to more autonomy, requires monitoring and a stop mechanismTrade-off: Maximum speed and autonomy, risk of errors and unsupervised token churn

It Will All Be HOOTL One Day - We’re Screwed

The research on long-term coherence when running autonomous agentic tasks I linked above suggests why HOOTL is not an option for most software developed today. But the question whether errors will continue to compound in long-running agentic tasks is still open. There is some evidence pointing in the opposite direction, too.

But I’ll go out on a limb here and claim that HOOTL might never happen for building software whose purpose is still being discovered. The reason is not AI imperfection. No, it’s us humans. It’s the old “the client doesn’t know what they want yet” problem. In such projects, AI cannot run without a human taking responsibility, because the requirements and decisions are formed through feedback on the artifact so far. Even if AI or developers were perfect, requirements never are.

If you can write the acceptance test before the work starts, the agent can probably close the loop. If you can’t, then you are the loop.

Agentic Engineering: HITL or HOTL?

So far, AI-assisted development or Agentic Engineering, as the cool kids call it nowadays, has mostly been Human-in-the-Loop, with developers approving most steps and decisions along the way. Which made sense: given the high stakes and complexity of software projects, early feedback was essential to keep the agent on track and prevent costly mistakes.

The higher the risk and/or the more costly a mistake is, the closer humans need to be in the loop. But with recent advances in model capabilities, human intervention is becoming an ever-growing impediment.

Tests are a great example - remember “step out of the loop and onto it” from the Test phase? They silently evolved from something largely HITL to HOTL over the course of 2026. At the beginning of the year, AI would generate some code and then I would take over and tell it what to do. “Run tests. Fix failures. Run tests. Fix failures. Make no mistakes this time.” That grew old faster than the latest TikTok hype.

The picture has changed completely. Nowadays, flagship models (and even the second-tier ones) will self-validate their output meticulously, without my intervention. They know how to run tests. They know how to fix what fails. It feels stupid having to tell them something they already know.

What Text-First Adds

Don’t worry, I’m not making you choose between Text-First and Loop Engineering. Text-First isn’t a loop itself - it’s the text a loop runs on. Addy Osmani puts it like this:

The model forgets everything between runs so the memory has to be on disk and not in the context. The agent forgets, the repo doesn’t.

Sounds familiar? That’s one of our three wins: context for AI. A loop needs a goal to verify against, skills that compound, and state that survives the run. Text-First leaves the goal and the state behind as a byproduct, and Phase 0 gives you the skills. What it adds: our second win, plus a phase loops tend to skip and a lower barrier to entry.

  • Documentation for humans. A loop’s memory is written for the machine. Text-First writes it for both, so it still makes sense when Sarah’s successor needs to know why.
  • Refactoring and doc gardening. Osmani warns that comprehension debt grows faster with every smooth loop “unless you read what the loop made”. Text-First has a phase for exactly that.
  • Nothing to set up. No automations, no sub-agents, no worktrees - a repo and a chat session are enough to start. And once you build a full loop, Text-First’s files are exactly what it reads.

The Loops of Text-First

Outer Loop: TextInner Loop: Code
Discuss → Design → PlanImplement ↔ Test
Iterating on text, not codeAgent changes, checks & corrects autonomously
HITL: Implementation starts only when the plan fitsHOTL: Human observes & intervenes if necessary

Refactor, where you would typically review and improve the code, is HITL again and it closes the cycle. Any insights gained here feed back into the documentation and planning for the next iteration of Text-First. Combine Kilo’s What Makes a Good AI Engineering Loop with Osmani’s article, and you get a checklist. Here’s how Text-First measures up:

Well-designed loopText-First
Clear GoalRequirements, endpoints & diagrams from Discuss/Design in doc/
Relevant ContextInclude artifacts selectively via file references (#file:, @file), Markdown instead of .docx/.pdf
Memory Outside the ChatPlan & documentation as Markdown in the repo, versioned with Git
Small, Reversible StepsPlan breaks down the task, Git as a safety net
Reliable FeedbackTests, static analysis & build as autocorrection
Clear Stop RuleVerifiable end (“tests are passing”), then review by humans

The loop lives in the repo, not in the chat. This is crucial, because the agent has no memory between runs. We could also call it “Memento-Driven Development”: Guy Pearce - the agent - forgets, but his Polaroid - the repo - doesn’t. It’s our job to give him that Polaroid.

It’s not the agent that learns, it’s the repo.

What About Brownfield?

I know what you’re thinking. “Obviously your fancy-pants non-framework framework is going to work in a toy greenfield scenario that’s clearly catered to it. But what happens when we leave this realm and enter the messy plane of real-life brownfield projects?” Can Text-First still deliver? Yes, and AI’s going to do the dirty work for you just like it did in the greenfield case.

Use it to reverse-document the existing codebase, so it can come up with suitable prompt customization files as required. Once the foundation is established, the rest is completely analogous to the greenfield case. It’s really just Phase 0 that is different. Instead of deriving the required files from discussion and prompts alone, this time the relevant documentation and decision records will have to be retrofitted in a joint effort by you filling in the why and AI documenting the how. If Sarah’s still around, now would be the time to buy her lunch.

The Real Payoff

Let’s take a step back and look at what all of this actually buys us. Seven prompts with one or two lines each led to 15 files with about 770 lines of code, including tests and documentation. A toy example at best, I know. The ratio won’t survive a real codebase unchanged, but the mechanism does.

Remember the equation from the beginning? Productivity is what’s left after subtracting rework. Every phase of Text-First attacks exactly that term. Quality goes up, because more of the relevant constraints are in the context when it matters. Variance goes down, because architecture and style are no longer a game of roulette rolled fresh with every prompt. And rework goes down, because mistakes are caught while they are cheap instead of surviving all the way into two thousand generated lines of code - and most of what remains is handled by the inner loop, without you.

That is how the last 30% becomes affordable. Not through a better model, not through the next tool du jour:

It’s not the AI that magically gets better with Text-First. It’s us getting better at explaining what we expect.

Key Takeaways

If you take only five things away from this article, make it these:

  1. Language is the universal interface - including to AI.
  2. Design the loop and own its boundaries. It’s not the agent that learns, it’s the repo.
  3. Documentation is finally affordable - take advantage of it.
  4. Context is king. One file, three purposes. Win-win-win.
  5. Text-First: If it can be text, it should be text.

Two years ago I was the guy smirking “this is blockchain all over again”. I was wrong, and I’m glad I gave it a second look, and a third. Still looking, actually, and fascinated by where this is heading. AI-assisted development rewards the same virtues software engineering has always rewarded - clear thinking, written down, kept up to date and close to the code. The difference is that, for the first time, someone reads everything we write and, even better, someone actually helps us maintain it.

No tool circus. No hocus-pocus. Just text.

Text-First.