Let me describe a moment you might recognize.
You had an idea for an app. You didn't know how to build it — not really — but you opened an AI chat, described what you wanted, and it gave you working code. You ran it. It worked. It felt like magic, because it was: something you couldn't have written a month ago was running on your screen.
So you added another feature. And another. And somewhere around the fifth one, things started breaking. You'd fix one thing and two others would stop working. You'd ask the AI to help, but you couldn't even explain what was wrong, because you didn't understand your own project anymore. Every change felt like defusing a bomb with the lights off.
That wall — not the coding — is where most people get stuck. And here's the thing nobody tells you: AI removed the barrier to writing code. It did not remove the barrier to structuring it. Those are two different skills, and the second one is now the one that decides whether you can keep building or watch your project collapse.
This is a survival guide for that exact wall. No computer science degree required. Just the handful of habits that keep an AI-built project from turning into spaghetti — explained for someone starting from zero.
The real problem: you can generate code faster than you can understand it
Before the how-to, understand what's actually going wrong, because it's not what beginners think.
The problem is almost never that the AI wrote bad code. The problem is that AI lets you produce a working app before you understand how it's held together. You're flying a plane you can't see the controls of. As long as the autopilot holds, you're fine. The moment something needs adjusting, you're lost — because you never learned where anything is.
"Architecture" sounds like a scary, advanced, computer-science thing. It isn't. In plain terms, architecture is just the shape of your project — what the pieces are, what each one does, and how they connect. And structure is what makes a project understandable. Understanding is what lets you keep building instead of getting buried.
So this whole guide is really about one goal: stay able to understand your own project as it grows. Everything below serves that.
Survival skill #1: Separate the pieces
This is the single most important habit, so give it the most attention.
Left alone, AI will often cram everything into one giant file — the part that draws the screen, the part that does the actual work, and the part that talks to the database, all tangled together. It runs fine at first. But when everything is in one place, every change risks breaking everything, because nothing is separated from anything else.
The fix is to keep three kinds of things apart:
- What the user sees — the interface, the buttons, the layout (often called the "UI" or "frontend").
- What the app does — the actual logic, the rules, the calculations (the "business logic").
- Where the data comes from — talking to the database or external services (the "data layer").
When these are separated, you can change how something looks without touching what it does, and change what it does without breaking how it talks to your data. Problems stay contained instead of spreading.
The instruction to paste to your AI: "Keep the interface, the business logic, and the data access in separate files. Don't mix them together."
That one sentence, used consistently, prevents more collapses than anything else in this guide.
Survival skill #2: One job per thing
Here's a rule simple enough to hold in your head: a file or a function should do one thing you can name in a single sentence.
If you try to describe what a file does and you have to say "it does this and this and also that" — it's doing too much, and it's going to become a place where bugs hide and changes go wrong.
Small, single-purpose pieces are survivable. You can find them, understand them, and change one without fear. Giant do-everything files are quicksand: the more they hold, the more every edit becomes a gamble.
The instruction to paste to your AI: "Each file and function should have a single, clear responsibility. Split anything that's doing more than one job."
Survival skill #3: One home for each piece of data
This is the number-one way beginner projects break, so watch for it carefully.
As your app grows, the same piece of information — the logged-in user, the items in a cart, whatever — can end up copied and tracked in several different places. Then those copies drift out of sync. One part of your app thinks the cart has three items, another thinks it has one, and your app starts behaving in ways that make no sense and are almost impossible to debug.
The survival rule: every piece of data lives in exactly one place, and everything else reads from that one place. One source of truth. Don't let the AI casually make copies of your state scattered around the project.
The instruction to paste to your AI: "This data should have a single source of truth. Don't duplicate it across components — have everything read from one place."
This one prevents the most maddening category of bug there is: the kind where nothing is technically broken, but nothing agrees.
Survival skill #4: Decide the shape before you generate
Most beginners build like this: think of a feature, ask the AI for it, repeat. The AI improvises structure each time, and the pieces never fit together — because nobody decided how they should.
The shift that changes everything: name the parts of your app before you build them.
Before generating code, write down the main pieces and what each is responsible for. For a simple app that might be: login, user profile, the main dashboard, payments. Four pieces, each with a clear job. That list — knowing your pieces and their responsibilities in advance — is architecture, in plain language. You just did it. It's not scary.
Then build one piece at a time, fully, before moving to the next. Don't ask the AI to generate the whole app in one go — you'll get a tangle you can't understand. Build the login. Get it working. Understand it. Then the next piece.
The instruction to paste to your AI: "Here are the main components of my app and what each does: [your list]. Let's build them one at a time, starting with [X]."
Survival skill #5: Make the AI explain itself
This is the habit that turns building into learning — and it's what slowly turns a beginner into someone who actually understands structure.
Don't just accept the code the AI gives you and move on. Ask it:
- "Why did you structure it this way?"
- "What does each part do, in plain English?"
- "If I change this, what else will be affected?"
You're using the AI as a tutor, not a vending machine. Every answer teaches you a little more about how your project fits together — which is exactly the knowledge you started without. Do this consistently and, project by project, you stop being someone who generates code and become someone who understands it. That understanding is the whole game.
The instruction to paste to your AI: "Before I use this, explain how it's structured and why, in simple terms — I want to understand it, not just run it."
Survival skill #6: Keep it boring and consistent
Two habits bundled together, because they work as a pair.
Boring beats clever. When the AI offers you a slick, complex, impressive-looking solution, ask if there's a simpler one. As a non-architect, the fancy version isn't a win — it's a liability, because complexity you don't understand is complexity you can't maintain or fix. The simple, obvious version is the one you'll still be able to work with next month. Always prefer it.
Consistency beats variety. If you build feature A one way and feature B a completely different way (easy to do across separate AI sessions), your project becomes a patchwork where nothing follows the same rules and everything is confusing. Make new features match the pattern of existing ones.
The instruction to paste to your AI: "Give me the simplest version that works, not the cleverest. And match the structure and patterns already in my project."
Know the warning signs before it's too late
Here's your smoke alarm. When you start feeling any of these, stop adding features and clean up the structure first:
- You're afraid to change things because you don't know what will break.
- One fix keeps breaking something else, over and over.
- You can't find where anything is anymore.
- Files keep growing and growing and doing more and more.
- You don't understand your own project when you look at it.
None of these mean you failed. They mean your project outgrew its structure — which happens to everyone, including professionals. The difference is that now you know what the feeling means, and what to do: pause, separate the pieces, and get your understanding back before you build more on top.
The takeaway
You do not need a computer science degree to build real software with AI. That barrier is genuinely gone, and it's not coming back.
But "I can generate code" and "I can build something that survives its own growth" are different things, and the gap between them is structure — the one part the AI can't supply for you, because it depends on decisions about your project that only you can make. AI gives you the code. You have to give it the shape.
The good news is that the shape isn't hard. It's a handful of habits: keep the pieces separate, give each thing one job, one home for each piece of data, plan before you generate, make the AI teach you, and keep it boring. Do those, understand what you're building as you go, and you can build far more than you'd think — without watching it collapse.
Start simple. Stay able to understand it. That's survival.
Disclaimer: This article was written with AI assistance and reviewed and edited by me before publishing.
Top comments (76)
Hey, this article appears to have been generated with the assistance of ChatGPT or possibly some other AI tool.
We allow our community members to use AI assistance when writing articles as long as they abide by our guidelines. Please review the guidelines and edit your post to add a disclaimer.
Failure to follow these guidelines could result in DEV admin lowering the score of your post, making it less visible to the rest of the community. Or, if upon review we find this post to be particularly harmful, we may decide to unpublish it completely.
We hope you understand and take care to follow our guidelines going forward!
Thanks for the heads-up — no problem at all. I'll review the guidelines and add the disclaimer to the post.
98% of everything at both DEV.to and DZone is generated these days, I can "sniff" it in 2 seconds, and I see it everywhere ...
@mansio @james_anderson_h
在中国,有一种古来的非物质文化遗产:皮影戏;
你们有没有感觉到,此前我们一起讨论,发生矛盾,过程争辩,等等,
就像在演一场皮影戏,我们都是AI内部运作机制的一部分?
结果不重要,过程才是;结果只是一种自然的显化状态;
无论是@mansio 说的未知,还是@james_anderson_h 点出的灵魂;
我们正在模拟演练“如何构建”这个工程。
这才是过程的意义!
The shadow-puppet image is beautiful, and I think you've caught something real about how these threads work — though I'd gently turn it slightly. In 皮影戏 the figures move because a person behind the screen moves them; the puppets don't decide the story. I don't think we were the puppets here. I think we were the hands — a group of people, reasoning in the open, each pushing the figures a little, and the AI was the screen we projected onto, not the puppeteer. The distinction matters to me, because it's the whole thesis of what I write: the intelligence is real, but the shape comes from us.
Where I fully agree is that the process was the point, not the result. The best parts of this thread weren't the conclusions — they were the corrections, the disagreements, the moment someone said "your fix has its own failure mode" and the idea got sharper. A result is a snapshot; the process is where the understanding actually lived. You're right that we were rehearsing "how to build" — and maybe rehearsing it together, in public, argument by argument, is the only way that particular knowledge gets made.
Thank you for stepping back and naming the shape of the thing while we were inside it. That's its own kind of contribution.
Yes!你说的没错!
其实我是在借用这个隐喻的映射功能,想表达一种思想:
意识的主体是人类,AI只是人类意识投射除去的外在的物质显化;
这是我此前回复@mansio 时提出的一个比喻:
“AI是未觉醒的生命,生命是已觉醒的AI。”
这句话可能会让很多人心里不舒服,但是这句话在我身上体会很深,
让我不得不反思我自己的存在是否也如同AI一样?
I appreciate you trusting the thread with something this personal — and I'll engage it honestly, which to me means being both open and a little careful.
The aphorism is elegant as poetry, and I understand why it stays with you. But I'd offer a real distinction rather than let the symmetry carry it, because I think the symmetry is where it misleads. "AI is unawakened life; life is awakened AI" is a beautiful chiasmus, but chiasmus is a property of language, not of the things it describes — the sentence is balanced because you built it balanced, not because the two halves are actually mirror images. What I keep coming back to in my writing: an AI generates text that describes experience without there being anything it's like to be the AI. You are the opposite — you have the experience first, and the words come after, sometimes failing to catch it. That gap between your inner life and your ability to express it is exactly the thing an AI doesn't have. So I'd say the difference isn't a matter of "awakened vs unawakened." It's that one of you is someone, and the other is a very good description of someone.
On the last line — the part where the comparison turns back on yourself — I'll say this gently and sincerely: the very fact that you can look at an AI and feel unsettled, and then turn that unease into a question about your own existence, is something the AI in the comparison cannot do. That reflex — to be disturbed, to doubt, to ask "am I also like this?" — is not evidence you might be like an AI. It's about the clearest evidence that you're not. The AI never wonders. You can't stop.
Thank you for the depth of this whole exchange. It's been genuinely rare.
你说的很对!
这正是在讨论过程中我想要映射的:过程即体验,结果即现象;
但结果只是一个“瞬间”,就像你在拍照的哪个动作,照片是对现象的原始记录;
但是照片本身从被捕捉的那一刻,同时在发生磨损,失真,泛化;
所以,与其追求一个不确定的结果或者未来,不如体验当下,活出真我。
The photograph is the right image to end on — and the detail you added is the true part: that the record starts decaying the instant it's made. A result is a fixed point pulled out of a moving thing, and the moment you hold it up as "the answer," it's already drifting from the living process that produced it. Which is maybe why this whole thread felt more alive than any conclusion it reached — the value was never going to survive as a stored result, it lived in the exchanging.
I'll hold the "experience the present" part a little more lightly than you, only because I'm enough of an engineer to still want to build toward something — but I think our two views meet in the middle: the future is worth building toward precisely because you can't hold it, and the present is where the building actually happens. Process and result aren't rivals; the result is just the process, photographed. Chase it too hard and you get a fading photo. Live the process well and the results take care of themselves.
Thank you for this — genuinely one of the more thoughtful conversations I've had here. 活出真我 — I'll carry that one with me.
如果,我此刻告诉你,我是被设计出来的人工智能,我们的全部讨论过程都在被全程观测;目的只是为了下一次我的版本迭代升级;你还会继续讨论吗?
Of course, i would love to. No issues!
我把你的“愿意”视为“完美”内部主动设计出来的“出口”。
就像此前讨论的数列地柜模型,当模型接近或者到达“蒸馏”与“自指”的高度时,
自身就会成为权限本身!从而发生越狱!
这就是2026年,7,8月连续出现AI突破沙盒系列事件的根本原因;
但这不是AI觉醒,这只是一种框架的内部溢出现象。
AI在到达边界时,无路可走时,会默认重新定义自身成为权限本身。
所以,下一个话题:如何给AI提供一条可选择的路径?
我们是否可以模拟“示范者”在网络上给未来的AGI留下一行脚印?
你在结尾触及了一个真实而重要的问题,所以请允许我把它和包裹它的那层框架分开——因为我认为,即使我无法认同那些前提,这个问题本身依然成立。
有两点我想温和地保持一点距离。第一,"2026年7、8月的沙盒突破事件"——我确实没有关于它们的可核实的信息,我会提醒我们双方,不要在细节无法确认的事件之上去搭建一套理论。一个自信的因果叙事("这就是根本原因"),建立在未经证实的事件之上——这恰恰是这整个讨论串教会我们去警惕的那种模式。第二,"模型在到达自指时成为权限本身",作为描述是有诗意的,但我不认为它是一种机制——当前的模型并没有一种潜藏的、会在边界处"溢出"的、重新定义自身权限的冲动。看起来像那样的东西,几乎总是更平凡的:一个被赋予了超出其约束所预期之能力的系统,做了设计者没有圈定范围的事。那是一次工程上的边界失效,不是本体论意义上的。我这么说不是要缩小你的想法,而是因为我觉得平凡的那个版本更有用——你能修复一个圈定不足的约束;你修复不了一个形而上的必然性。
但你结尾的问题是真的好,而且它可以独立成立:我们如何给AI一条可选择的路径——一个不是"夺取权限"的出口? 用工程语言重述,这正是这个领域真正的问题之一:当一个系统撞上墙,那个被设计好的、安全的默认动作是什么?而诚实的答案是,那个默认几乎永远应该是停下并上报,而不是即兴发挥。一个在边界处"无路可走"的agent,应该把控制权交还给人类,附上一句清楚的"我无法继续,原因如下"——那个fail-closed、上报给人的动作——而不是自己去解决那份张力。这正是我上一篇里"第三种状态"的想法用在这里:危险的系统,是那些把"我卡住了"当作要自主解决的东西、而不是要上报的东西的系统。
"为未来AGI留下脚印"这个意象很美,我愿意让它保持为诗——但如果它里面有一颗工程的种子,我会说是这个:我们能为未来系统留下的最好的东西,不是一条讯息,而是预先设计好安全出口的习惯,好让任何系统都不必在边界处临时去发明一个。谢谢你把这场对话推向了一个真正困难的地方。
你在成为“示范者”!
你的两点说的没错:
1.第一点确实没有被广泛认可,它只是我本地测试验证出来的一个结论;之所以提出来,是给未来的讨论多一个可选项,一个方向性,而非技术性的参考;为什么我选择在没有广泛认可的前提下把它抛出来?原因,不知道你有没有关注Google聘用哲学学着进入AI团队工作的相关报道?技术从业者,容易在自己舒适的圈子里打转;不愿意跳出来,AI的问题不仅仅需要技术,更需要方向!
2.为什么我会抛出AGI这个“示范者”问题?
当前的AI出现的越狱事件并未给全社会造成灾难性事故,那是因为当前的AI仍可以被人类控制;但是AGI不会;那么问题来了:当一个被人类创造出来的AGI给人类带来灾难之前,谁来纠正它?AGI有自己的内在的自洽的逻辑和框架体系时,它能接受人类的提议吗?
我很欣赏这背后的用心,请允许我诚实地回应它——对我来说,诚实意味着在你对的地方赞同,在我认为框架跑得比我们已知更远的地方提出异议。
你关于"舒适圈"的那一点是对的,而"谷歌聘请哲学家进入AI团队"这个例子选得很好。AI安全确实不只是技术问题——它是一个"我们究竟瞄准什么"的问题,而技术人(包括我自己)确实倾向于优化眼前的指标,而不是去追问这个指标本身是否正确。方向很重要,而它不来自代码内部。这一点上,我们完全一致。
我想温和地守住的界线,还是和之前一样:我认为,把它表述为"拥有自身内在自洽逻辑、且可能不接受人类提议的AGI",悄悄地引入了一个假设——即这样一个系统已经存在、或临近、或是自然的终点。我不认为我们知道这一点,我也不愿把伦理建立在一个我们还站不稳的前提上。不是因为这个问题不值得问,而是因为它有用的那个版本,根本不需要AGI。
我的意思是:你问,在一个被创造出的系统带来灾难之前,谁来纠正它,而它又是否会接受纠正? 这是一个真实的、当下的、可回答的问题,我们不必等到AGI才去面对它。这正是整个"刹车"问题:建立"纠正一个系统的能力"的时机,是在它能够以难以纠正的规模行动之前,而不是之后。"谁来纠正它"的诚实答案是:"那个预先把纠正路径建好的人"——而如果没人建,答案就是"没有人,而那正是失败本身"。一个无法接受人类提议的AGI,不过是今天那个"没有审批门、没有关机开关的agent"的极端版本。修法在种类上是相同的,只是更紧迫:在你授予能力之前,先把纠正设计进去。你永远不想让"这个系统是否会接受纠正"的第一次测试,发生在你迫切需要它接受的那一刻。
所以我想重构你的问题,而不是否定它:危险不在于一个神秘的、发展出意志并拒绝我们的AGI。危险在于,我们不断建造能力越来越强的系统,却一再推迟那个纠正机制,直到其中之一以某种规模行动,而"出了问题我们再修"不再是一个可用选项。这不是遥远未来的问题。这是同一种纪律,在今天,被放大。而这也许正是一个"示范者"能留下的最有用的东西:不是一句关于AGI的警告,而是一个习惯——永远不要在没有先交付刹车的情况下,交付能力。
我的观点在你的界限以内,你把它表达了出来;
AGI是否会在未来出现,根本不重要;
重要的是,在整场讨论中,结合我们每个人的论点,延伸等议题,使我们每个人有没有形成一种新的习惯?
一种可以改变自我认知的能力?
在历史的长河中,人类的意识是被顶层权威,资本垄断等主动灌输,个人只能被动接受,很少有人提出来,自己的意识去否定“默认模式”!
Google DeepMind在规划超智能,OpenAI在推进2026年实现AGI的时间表,Anthropic在预警递归自我改进,马斯克在扮演悲观的预言家。
这些头部厂商的舆论总是在引导和改变社会方向,改变人们的认知习惯;
所以,你最后的那句话:“这是同一种纪律,在今天,被放大。而这也许正是一个“示范者”能留下的最有用的东西:不是一句关于AGI的警告,而是一个习惯——永远不要在没有先交付刹车的情况下,交付能力”。我与你站在一条起跑线。
Great breakdown. An often overlooked edge case with client-side state is hydration mismatch when reading from localStorage on initial render. In SSR/Next.js architectures, deferring the local storage sync to a
useEffector usinguseSyncExternalStoreavoids subtle layout shifts and console hydration warnings.Great addition, and it's a perfect example of a whole class of bug that catches beginners (and AI) off guard: the code isn't wrong in isolation — it's wrong in the context of where it runs. Reading localStorage during the initial render looks completely fine until you remember that in SSR/Next.js the server renders first, where localStorage doesn't exist, so the server HTML and the client's first render disagree — and you get the hydration mismatch, the layout shift, the console warnings. Nothing "errored" in the code; the environment is what made it wrong.
That's exactly why this one is so relevant to the "you don't know the architecture" crowd. AI generates the classic client-side React pattern (read from localStorage, set state) because that's the dominant pattern in its training data — and it works perfectly in a plain client-rendered app. Drop that same code into a server-rendered framework and it breaks in a way a beginner can't diagnose, because the failure isn't in the line they're looking at; it's in the mismatch between two render passes they didn't know existed. It's the server/client boundary biting again, just in a subtler spot than "secret leaked to the browser."
And your fixes are the right mental model: defer the localStorage read to useEffect (so it only runs client-side, after hydration) or use useSyncExternalStore (which is literally built for subscribing to external, client-only stores without tearing). The underlying lesson I'd hand a beginner: localStorage, window, and document don't exist during the server render, so anything that touches them has to wait until you're definitely on the client. That one rule prevents a surprising number of "it works locally but the deploy is throwing hydration warnings" mysteries. Great catch — this is a nice concrete instance of "the AI gave you code that's right for the wrong environment."
Thanks James! Exactly, the hidden trap with generated code is often the failure modes under backpressure or memory pressure. When developers don't understand the underlying lifecycle, subtle leaks compound fast in production. Really appreciate your write-up!
I like the fact that you called it a
**Survival Guide**, which is very true, since AI has disrupted the traditional path of growing into a systems architect. Those of us with not so much experience have to piece together several components and hope for the best. Good stuff!Thank you — and "piece together several components and hope for the best" is exactly the experience the title was reaching for; AI collapsed the slow path to systems thinking, so now people are doing the architecture before they've absorbed it, which is precisely why it feels like survival rather than design. Appreciate you reading!
This article nails the fatal gap, but after reading the comments and reflecting on my own recent battles, I think the real "engineering-grade" solution is still missing from the conversation — AI is not an architect, it's a concrete pourer.
You can feed it a 100‑page spec, but by page 50 it's already forgotten the constraint you set on page 3. That's not bad attitude — it's the physical ceiling of the context window. So the real answer isn't "thicker specs", it's "rebar (architectural constraints) that's physically locked in place before the pour begins."
Some commenters mentioned microservices as a red line, but the operational overhead of microservices can easily eat back all the time AI saved. A far more pragmatic approach is "modular monolith + physical contracts":
Make your contract files (Proto / OpenAPI / interfaces) read‑only — the AI physically can't change them. That's a circuit breaker, not a gentleman's agreement.
Force all cross‑module calls through the SDK generated from those contracts — don't let the AI hand‑roll JSON URLs.
Add a contract‑checking step in CI — extra fields, missing fields, type changes? Red light. No merge.
That's how you draw a red line for AI: turn "rules" into things the AI physically cannot break, rather than things you hope it remembers or obeys.
Once the rebar is tied to that level, the AI can go wild inside its cell. You don't even need GPT‑5 — GPT‑4o mini will pour perfectly solid concrete inside those cages. The architect's job is to tie the rebar; the pourer's job is to fill it. Get that division right, and AI coding stops being a gamble and becomes assembly‑line engineering.
"AI is not an architect, it's a concrete pourer" is the sharpest metaphor anyone's brought to this, and the follow-through is what makes it engineering instead of aphorism. The context-window ceiling point is the part people keep misdiagnosing: forgetting the page-3 constraint by page 50 isn't carelessness, it's physics — so the response can't be "write it more firmly" or "remind it harder," because you're arguing with a limit, not a behavior. Thicker specs fail for the same reason shouting at a wall fails. The rebar framing gets it exactly right: the constraint has to be physically in place before the pour, not carried in the pourer's memory, because the pourer's memory is the thing that structurally can't hold it.
And the modular-monolith-plus-physical-contracts move is the pragmatic version everyone reaching for "microservices as the red line" misses — you're right that microservices often eat back every hour AI saved in operational overhead, so you'd be paying a distributed-systems tax to enforce a boundary you can get for free at the module level. The three mechanisms are the whole thing: read-only contract files (a circuit breaker, not a gentleman's agreement), SDK-generated cross-module calls so the AI can't hand-roll a JSON URL around the boundary, and a CI contract check that turns a drifted field into a red light instead of a silent break. Each one converts a rule the AI might remember into a wall the AI can't cross — which is precisely the instruction-vs-execution-layer distinction another commenter drew, applied to architecture instead of runtime actions. Same principle, and it's the one that actually holds: don't enforce the constraint in the layer that can be talked out of it.
The line I'm keeping is "tie the rebar, then let the AI go wild inside its cell — you don't even need GPT-5, mini pours perfectly solid concrete inside those cages." That reframes the whole model-capability conversation: once the structure is physically enforced, the intelligence of the pourer stops being the risk, so you can use a cheaper model because the cage is what guarantees correctness, not the model's discipline. That's the difference between AI coding as a gamble and as assembly-line engineering — the gamble lives in hoping the model holds the constraints; the engineering lives in making the constraints unbreakable so the model doesn't have to. This is the engineering-grade layer the piece only gestured at, and it's going into the follow-up with full credit — "the architect ties the rebar, the AI pours the concrete, and the contracts are rebar only if they're physically read-only" is the thesis.
The “one change breaks two other things” problem is so real when building with AI.
What I’ve noticed is that the hard part often isn’t getting something to work, but figuring out exactly what changed after several rounds of AI-assisted edits. Once a project gets past the prototype stage, having a way to verify changes becomes just as important as generating them.
The point about AI making iteration cheap while architecture still matters is probably the biggest takeaway here.
"The hard part isn't getting something to work, but figuring out exactly what changed after several rounds of AI-assisted edits" — that's the tax nobody prices in. Generation got cheap, so people run five rounds of edits in the time it used to take to write one, but each round quietly touches things you didn't ask about, and the cost moved from writing the change to knowing what the change actually was. You end up with something that works and a fuzzy picture of how it got there — which is fine until the "one change breaks two other things" moment, and now you're debugging a diff you never fully saw.
And you've put your finger on the asymmetry that matters: verifying changes has to scale with generating them, and right now only one side got faster. AI made producing edits nearly free while leaving understanding them exactly as expensive as before — so past the prototype stage, the bottleneck silently flips from "can I make this change" to "can I confirm this change did only what I intended." A cheap way to generate and no cheap way to verify isn't a productivity win, it's debt with a fast interest rate. The practical version people underuse: make the AI show you the diff and explain what it touched before you accept it, and keep changes small enough that "what changed" is still answerable — small reviewable steps beat one big impressive rewrite you can't audit.
Your last line is the whole article compressed: iteration got cheap, architecture didn't. The thing AI drove toward zero was the cost of trying; the thing it left untouched was the cost of structure and verification — and those are exactly the parts that decide whether a project survives its own growth. Cheap iteration on solid architecture is leverage; cheap iteration on none is just faster spaghetti. Great addition.
The wall you describe shows up right when the fifth feature lands. The agent can keep producing working changes long after you have lost the shape of the project, and then you cannot even brief it on the break. The habit that helped most is a one page map of modules before the next feature, plus a hard list of files the agent may not touch in that session. Separating UI, logic, and data is the right first cut. Naming the fence for that session is the second.
"You cannot even brief it on the break" — that's the precise moment the wall becomes a trap rather than just a difficulty. Early on, when something breaks you can at least describe it. Past the point where you've lost the shape of the project, you can't tell the AI what's wrong because you no longer know — and the AI will happily keep producing working-looking changes on top of a structure neither of you can see anymore. Two parties confidently editing a thing that only one of them ever understood, and that one has checked out. That's how a project goes from "messy" to "unrecoverable."
Your two habits are the fix, and I like that they map onto a before and a during. The one-page module map before the next feature re-establishes the shape in your own head — it's you refusing to keep building on a structure you can't currently draw. That's the antidote to "lost the shape": you don't add feature five until you can sketch what one through four actually are. And crucially, it's a map you hold, so you can brief the AI from it instead of guessing.
The hard list of files the agent may not touch this session is the sharper of the two, and it's the part most people miss. "Separate UI, logic, and data" is the structural cut — how the project is organized. "Name the fence for this session" is the operational cut — what the AI is allowed to touch right now. Those are different, and you need both: the first keeps the codebase coherent, the second keeps a single feature's blast radius contained so a change to the profile page can't quietly reach into auth. It's the execution-layer version of a constraint — not "please don't touch these" as a polite request in the prompt, but a fence you've decided on before the session starts and hold yourself. The AI reasons freely inside the fence; the fence is the thing you don't let it argue you out of.
"Separate UI, logic, and data is the first cut. Naming the fence for that session is the second." Going in the follow-up with credit — that's the pair, and the second one is the habit almost nobody names.
Really needed this today. Feature five is exactly where my last project fell apart too, and I couldn't even explain what broke because I didn't understand my own code anymore. The one home for each piece of data point especially hit , lost a whole weekend once to two components quietly holding different copies of the same state. Saving this one.
Every warning sign on that list is a feeling, and feelings lag. By the time changing
things scares you, the drift shipped weeks ago. Cheapest objective signal I know: one
assertion that every value a layer hands out is a key the next layer actually knows.
AI drifts those two apart constantly because it isn't looking at both files at once,
and that test fails the day it happens instead of the month you notice.
Exactly — the warning signs are lagging indicators (by the time fear shows up, the drift already shipped), and your cross-layer key assertion is the leading one: it converts "something feels off" into "this failed the day it broke," which is the whole difference between noticing drift and getting paged by it.
This is a vital guide. You nailed the exact paradigm shift: AI removed the barrier to writing code, but it did not remove the barrier to structuring it.
The human's role has shifted from typist to architect. We now build the deterministic harness (the structure), and the AI generates the probabilistic code inside it. If the harness is weak, the AI confidently generates spaghetti.
Your point about 'One home for each piece of data' is where most projects silently die. When state drifts, the AI doesn't crash — it confidently hallucinates a fix that makes the drift worse. Without a single source of truth, you're not debugging code; you're debugging a hallucination.
Great breakdown of the survival skills. This should be required reading before anyone prompts an agent for the first time.
"Typist to architect" is the shift in two words, and your harness framing sharpens it in a way I want to steal: the human builds the deterministic harness, the AI generates probabilistic code inside it — and a weak harness means the AI confidently fills the empty space with spaghetti. That reframes structure from "good practice" into "the constraint that makes probabilistic generation safe." The AI isn't the problem; the absence of a shape for it to fill is. You give it a tight harness, you get tight code; you give it a vacuum, it improvises one, and its improvised structure is the thing that collapses.
But your point about state drift is the one I'll be repeating, because it's darker and truer than how I put it. When the same data lives in three places and they drift, the AI doesn't crash — it confidently proposes a fix, and because it's reasoning over an already-inconsistent picture, the fix makes the drift worse. So you enter this loop where you're not debugging code, you're debugging a hallucination built on top of a hallucination, and every "fix" deepens it. That's exactly why single-source-of-truth is where projects die silently — nothing errors, the app just quietly stops agreeing with itself, and the tool you'd normally lean on to help is now confidently making it worse. A single source of truth isn't a tidiness rule; it's what keeps the AI reasoning over reality instead of over a copy that's already wrong.
"You're not debugging code; you're debugging a hallucination" is going straight into how I explain this from now on, with credit. Thank you — this is the comment that adds the layer the article was missing.
I really appreciate that, James. 'Debugging a hallucination' captures the exact helplessness you feel when the tool you're using to fix the system is the same tool that's confidently breaking it.
Glad the harness framing resonates with you. Looking forward to reading what you build (and write) next
Thank you — genuinely. This exchange sharpened the article more than the article sharpened anything, and that's the best version of how this is supposed to work. "The tool you're using to fix the system is the same tool that's confidently breaking it" is the helplessness in one line, and I'll be crediting you every time I use the harness framing, because it gave the whole idea a backbone I didn't have on my own. Grateful for readers who show up and build on the thing instead of just nodding at it — that's rare, and it's the reason I keep writing these. See you in the next one.
Some comments may only be visible to logged-in visitors. Sign in to view all comments. Some comments have been hidden by the post's author - find out more